# Create Square Pipes with RhinoScript

Developer: RhinoScript
Summary: Demonstrates how to create square pipes using RhinoScript.

## Example

``` Option Explicit

Sub SquarePipe()

' Pick the input, or path, curve
Dim strCrv
strCrv = Rhino.GetObject( "Select curve", 4 )
If IsNull( strCrv ) Then Exit Sub

' Specify the lengths of the sides of the square
Dim dblLength
dblLength = Rhino.GetReal( "Length of sides", 1.0, 0.0 )
If Not IsNumeric(dblLength) Or dblLength <= 0 Then Exit Sub

' Determine the curve's starting point
Dim arrStart
arrStart = Rhino.CurveStartPoint( strCrv )

' Determine the parameter at the starting point
Dim dblParam
dblParam = Rhino.CurveClosestPoint( strCrv, arrStart )

' Detemine the curve's curvature at the starting point. This
' will return two vectors that we can use to cook up the
' coordinates of the square
Dim arrCurvature
arrCurvature = Rhino.CurveCurvature( strCrv, dblParam )

' Cook up x, y, and z vectors
Dim arrX, arrY, arrZ
arrZ = VectorUnitize( arrCurvature(1) )
arrX = VectorUnitize( arrCurvature(4) )
arrY = VectorUnitize( VectorCrossProduct(arrZ, arrX) )

' Scale the vectors based on the user input
arrX = VectorScale( arrX, dblLength )
arrY = VectorScale( arrY, dblLength )

' Cook up some temporary points
Dim x0, x1, y0, y1
x0 = PointAddVector( arrStart, arrX )
x1 = PointAddVector( arrStart, VectorNegate(arrX) )
y0 = PointAddVector( arrStart, arrY )
y1 = PointAddVector( arrStart, VectorNegate(arrY) )

' Define the points of the square
Dim arrPoints(4)
arrPoints(0) = PointAddVector( x0, VectorNegate(arrY) )
arrPoints(1) = PointAddVector( y1, VectorNegate(arrX) )
arrPoints(2) = PointAddVector( x1, arrY )
arrPoints(3) = PointAddVector( y0, arrX )
arrPoints(4) = arrPoints(0)

' Create the square
Dim strSqr

' Extrude the polyline along the input curve
Rhino.ExtrudeCurve strSqr, strCrv

' Delete polyline
Rhino.DeleteObject strSqr

End Sub

Public Function VectorUnitize(v)
VectorUnitize = Null
If Not IsArray(v) Or (UBound(v) <> 2) Then Exit Function
Dim dist, x, y, z, x2, y2, z2
x = v(0) : y = v(1) : z = v(2)
x2 = x * x : y2 = y * y : z2 = z * z
dist = x2 + y2 + z2
If (dist < 0.0) Then Exit Function
dist = Sqr(dist)
x = x / dist
y = y / dist
z = z / dist
VectorUnitize = Array(x, y, z)
End Function

Public Function VectorNegate(v)
VectorNegate = Null
If Not IsArray(v) Or (UBound(v) <> 2) Then Exit Function
VectorNegate = Array(-v(0), -v(1), -v(2))
End Function

Public Function VectorCrossProduct(v1, v2)
VectorCrossProduct = Null
If Not IsArray(v1) Or (UBound(v1) <> 2) Then Exit Function
If Not IsArray(v2) Or (UBound(v2) <> 2) Then Exit Function
Dim x, y, z
x = v1(1) * v2(2) - v1(2) * v2(1)
y = v1(2) * v2(0) - v1(0) * v2(2)
z = v1(0) * v2(1) - v1(1) * v2(0)
VectorCrossProduct = Array(x, y, z)
End Function

Public Function VectorScale(v, d)
VectorScale = Null
If Not IsArray(v) Or (UBound(v) <> 2) Then Exit Function
If Not IsNumeric(d) Then Exit Function
VectorScale = Array(v(0) * d, v(1) * d, v(2) * d)
End Function