Rain

Part of a library of environmental effect graphics generators this Rhino Script produces a series of lines which fall like rain upon Rhino’s cplane.  If a droplet hits there is a splash. The user can input the number clusters where the rain will fall from, the relative radius of the cluster, the percentage of the way that the rain can fall short as well as a few other conditions.  The rain is colored with a gradient according to the distance along the V domain of the surface to allow for the production of depth.

Rhino Script

Option Explicit
'Script written by <insert name>
'Script copyrighted by <insert company name>
'Script version Sunday, March 28, 2010 5:08:39 PM

Call Main()
Sub Main()
	Dim strSurface, arrInputs
	strSurface = Rhino.GetObject("Select Surface to Rain From", 8, True)
	If isNull(strSurface) Then Exit Sub
	
	arrInputs = Rhino.PropertyListBox(array("Sources", "Stream Radius", "Droplets", "Rate 0-1", "Splash Radius", "Stream Angle Radius"), array(50, 0.1, 10, 0.5, 0.5, 4), "Rain Parameters", "Rain Parameters")
	If isNull(arrInputs) Then Exit Sub
	
	Call reparameterize(strSurface)	
	Call Rhino.EnableRedraw(False)
	Call rainMaker(strSurface, arrInputs(0), arrInputs(1), arrInputs(2), arrInputs(3), arrInputs(4), arrInputs(5))
	Call Rhino.EnableRedraw(True)
	
End Sub
Function rainMaker(strSurface, dblCount, dblDispersion, dblDensity, dblRate, dblSplash, dblVarience)
	rainMaker = Null
	Dim i, j, k, a, w, v, s, t, u, z, clr, var
	Dim srfDom(1),srfD(1),srfA(1),srfR(1),srfS(1),srfE(1),pt(1), r(1)
	Dim ln(), spl(), temp(3)
	
	For i = 0 To 1 Step 1
		srfDom(i) = Rhino.surfacedomain(strSurface, i)
		srfD(i) = (srfDom(i)(1) - srfDom(i)(0))
		srfA(i) = srfD(i) - srfD(i) * dblDispersion
		srfR(i) = srfD(i) * (dblDispersion / 2)
		srfS(i) = srfDom(i)(0) + srfD(i) * (dblDispersion / 2)
		srfE(i) = srfDom(i)(1) - srfD(i) * (dblDispersion / 2)
	Next
	
	w = 0
	a = 0
	var = rnd()
	For i = 0 To dblCount Step 1
		u = srfS(0) + rnd() * srfA(0)
		v = srfS(1) + rnd() * srfA(1)
		r(0) = srfR(0) / 2 + rnd() * (srfR(0) / 2)
		r(1) = srfR(1) / 2 + rnd() * (srfR(1) / 2)
		clr = v / srfE(1)
		For j = 0 To dblDensity Step 1
			ReDim Preserve ln(w)
			pt(0) = Rhino.EvaluateSurface(strSurface, array(u + rnd() * r(0), v + rnd() * r(1)))
			pt(1) = array(pt(0)(0) + dblVarience * sin(PI * 2 * var), pt(0)(1) + dblVarience * cos(PI * 2 * var), 0)
			t = 1 - rnd() * dblRate
			ln(w) = Rhino.ScaleObject(Rhino.AddLine(pt(0), pt(1)), pt(0), array(t, t, t), False)
			pt(1) = Rhino.CurveEndPoint(ln(w))
			
			Call Rhino.ObjectColor(ln(w), RGB(clr * 255, clr * 255, clr * 255))
			
			If pt(1)(2) < 0.1 Then
				ReDim Preserve spl(a)
				For k = 0 To 3 Step 1
					t = rnd()
					temp(k) = Rhino.AddLine(pt(1), array(pt(1)(0) + dblSplash * sin(PI * 2 * t), pt(1)(1) + dblSplash * cos(PI * 2 * t), pt(1)(2) + dblSplash * sin(PI * t)))
					Call Rhino.ObjectColor(temp(k), RGB(clr * 255, clr * 255, clr * 255))
				Next
				spl(a) = temp
				a = a + 1
			End If
			w = w + 1
		Next
	Next
	
	rainMaker = array(ln, spl)
End Function
Function reparameterize(strObjectID)
	If Rhino.IsCurve(strObjectID) = True Then
		Call rhino.SelectObject(strObjectID)
		Call rhino.Command("reparameterize 0 1", False)
		Call rhino.UnselectAllObjects()
	End If
	If Rhino.IsSurface(strObjectID) = True Then
		Call rhino.SelectObject(strObjectID)
		Call rhino.Command("reparameterize 0 1 0 1", False)
		Call rhino.UnselectAllObjects()
	End If
End Function