Mathematical Form Scripts

RhinoCommon Code

Mobius

Implemented in a VB.NET scripting component for Grasshopper.

  Private Sub RunScript(ByVal U As Integer, ByVal V As Integer, ByVal R As Double, ByVal T As Double, ByVal S As Double, ByVal D1 As Interval, ByVal D2 As Interval, ByRef Srf As Object) 

    Dim pointslist As New List (Of Point3d)
    Dim psurface As NurbsSurface

    Dim urange0 As Double = D1.Min
    Dim urange1 As Double = D1.Max
    Dim vrange0 As Double = D2.Min
    Dim vrange1 As Double = D2.Max

    Dim ustep As Double = Math.Abs(urange1 - urange0) / (U - 1)
    Dim vstep As Double = Math.Abs(vrange1 - vrange0) / (V - 1)
    Dim ucount As Double = 0
    Dim vcount As Double = 0

    For i As Double = urange0 To urange1 Step ustep
      vcount = 0
      For j As Double = vrange0 To vrange1 Step vstep

        Dim x As Double = (R + j * Math.cos(T * i)) * Math.cos(i)
        Dim y As Double = (R + j * Math.cos(T * i)) * Math.sin(i)
        Dim z As Double = j * Math.sin(T * i)

        Dim mypoint As New Point3d(x * S, y * S, z * S)
        pointslist.Add(mypoint)

        vcount = vcount + 1
      Next
      ucount = ucount + 1
    Next

    psurface = NurbsSurface.CreateFromPoints(pointslist, ucount, vcount, 2, 2)

    Srf = psurface
  End Sub

Klein

Implemented in a VB.NET scripting component for Grasshopper.

  Private Sub RunScript(ByVal U As Integer, ByVal V As Integer, ByVal R As Double, ByVal T As Double, ByVal S As Double, ByVal D1 As Interval, ByVal D2 As Interval, ByRef Srf As Object) 

    Dim pointslist As New List (Of Point3d)
    Dim psurface As NurbsSurface

    Dim urange0 As Double = D1.Min
    Dim urange1 As Double = D1.Max
    Dim vrange0 As Double = D2.Min
    Dim vrange1 As Double = D2.Max

    Dim ustep As Double = Math.Abs(urange1 - urange0) / (U - 1)
    Dim vstep As Double = Math.Abs(vrange1 - vrange0) / (V - 1)
    Dim ucount As Double = 0
    Dim vcount As Double = 0

    For i As Double = urange0 To urange1 Step ustep
      vcount = 0
      For j As Double = vrange0 To vrange1 Step vstep

        Dim x As Double = (R + Math.cos(T * i) * Math.sin(j) - Math.sin(T * i) * Math.sin(2 * j)) * Math.cos(i)
        Dim y As Double = (R + Math.cos(T * i) * Math.sin(j) - Math.sin(T * i) * Math.sin(2 * j)) * Math.sin(i)
        Dim z As Double = Math.sin(T * i) * Math.sin(j) + Math.cos(T * i) * Math.sin(2 * j)

        Dim mypoint As New Point3d(x * S, y * S, z * S)
        pointslist.Add(mypoint)

        vcount = vcount + 1
      Next
      ucount = ucount + 1
    Next

    psurface = NurbsSurface.CreateFromPoints(pointslist, ucount, vcount, 2, 2)

    Srf = psurface
  End Sub

Processing

Supershape 3D

Implemented using the iGeo library.

import igeo.*;
import processing.opengl.*;
 
size(480, 360, IG.GL);
 
//supershape parameters
float m = 14.23;
float a = -0.06;
float b = 2.78;
float n1 = 3.74;
float n2 = -.48;
float n3 = 1.46;
 
int unum = 50;
int vnum = 50;
float uinc = PI/(unum/2);
float vinc = (PI/2)/(vnum/2);
 
//points array
IVec[][] mypts = new IVec[unum+1][vnum+1];
 
//math stuff
float theta = -PI;
for(int i = 0; i<=unum; i++) {
  float phi = -PI/2;
  float r1 = 1/pow(pow(abs(cos(m*theta/4)/a),n2) + pow(abs(sin(m*theta/4)/b), n3), 1/n1);
  for(int j = 0; j<=vnum; j++){
    float r2 = 1/pow(pow(abs(cos(m*phi/4)/a),n2) + pow(abs(sin(m*phi/4)/b),n3), 1/n1);
    float x = r1*cos(theta) * r2*cos(phi);
    float y = r1*sin(theta) * r2*cos(phi);
    float z = r2*sin(phi);
 
    mypts[i][j] = new IVec(x,y,z);
    new IPoint(x,y,z).clr(abs(1./theta),0,abs(1./phi));
 
    phi = phi + vinc;
  }
  theta = theta + uinc;
}
 
//create new surface
new ISurface(mypts);

Revit API

Sine Surface

Implemented within the Revit API as a conceptual mass.

Dim ref_ar_ar As ReferenceArrayArray = New ReferenceArrayArray()
Dim XYZ As Autodesk.Revit.Geometry.XYZ

For u As Double = 0 To 4 * Math.PI Step Math.PI / 4
  Dim rfptsarr As ReferencePointArray = New ReferencePointArray()
  For v As Double = 0 To 4 * Math.PI Step Math.PI / 4

    Dim refpt As Autodesk.Revit.Elements.ReferencePoint

    Dim x As Double
    Dim y As Double
    Dim z As Double

    x = 10 * u
    y = 10 * v
    z = 10 * Math.Cos(u) + 10 * Math.Sin(v)

    XYZ = revit_app.Create.NewXYZ(x, y, z)
    refpt = revit_doc.FamilyCreate.NewReferencePoint(XYZ)

    rfptsarr.Append(refpt)
  Next
  Dim crv As CurveByPoints = revit_doc.FamilyCreate.NewCurveByPoints(rfptsarr)
  Dim ref_ar As ReferenceArray = New ReferenceArray()
  ref_ar.Append(crv.GeometryCurve.Reference)
  ref_ar_ar.Append(ref_ar)
Next

Dim loftform As Autodesk.Revit.Elements.Form = revit_doc.FamilyCreate.NewLoftForm(True, ref_ar_ar)

Supershape3D using RevitPythonShell

Implemented using RevitPythonShell in a conceptual mass.

import math
import clr
clr.AddReference('RevitAPI')
clr.AddReference('RevitAPIUI')
from Autodesk.Revit.DB import *
 
doc = __revit__.ActiveUIDocument.Document
 
t = Transaction(doc,'undo')
 
t.Start()
 
#This script creates a 3D Supershape using lofted segments.
#Copyright (c) 2011, Nathan Miller, The Proving Ground
#The Proving Ground,  http://nmillerarch.blogspot.com
 
#3D supershape parameters
m = 15.97
a = 0.0486
b = 5.36
n1 = .2624
n2 = -.29
n3 = 1.5
 
ustep = 50
vstep = 50
 
piA = math.pi *.5
piB = math.pi *.5
 
#Because curves will eventually become absorbed into the loft form, it is important to create two sets of the same curve.
#This method is a workaround for being unable to connect all curves into one single lofted shape.
 
#Create ReferenceArrayArrays
refarar1 = ReferenceArrayArray()
refarar2 = ReferenceArrayArray()
 
#The math part...
theta = -piA
while (theta <= piA):
    phi = -piB/2
    r1 = 1/(((abs(math.cos(m*theta/4)/a))**n2+(abs(math.sin(m*theta/4)/b))**n3)**n1)
    refptsarr = ReferencePointArray()
    while (phi <= piB/2):
        r2 = 1/(((abs(math.cos(m*phi/4)/a))**n2+(abs(math.sin(m*phi/4)/b))**n3)**n1)
        x = r1 * math.cos(theta) * r2 * math.cos(phi)
        y = r1 * math.sin(theta) * r2 * math.cos(phi)
        z = r2 * math.sin(phi)
        myXYZ = XYZ(x,y,z)
        refptsarr.Append(doc.FamilyCreate.NewReferencePoint(myXYZ))
 
        #Increment phi
        phi = phi + (piB/2 / (vstep/2))
    #Increment theta
    theta = theta + (piA / (ustep/2))
 
    #Comment out everything below to quickly test the point cloud shapes
    #Surface geometry takes a long time to generate.... needs to be faster!
 
    #create the curves
    crv1 = doc.FamilyCreate.NewCurveByPoints(refptsarr)
    crv2 = doc.FamilyCreate.NewCurveByPoints(refptsarr)
 
    #create reference arrays
    refar1 = ReferenceArray()
    refar2 = ReferenceArray()
 
    #Append curve refences to the reference arrays
    refar1.Append(crv1.GeometryCurve.Reference)
    refar2.Append(crv2.GeometryCurve.Reference)
 
    #Append ReferenceArrays to ReferenceArrayArrays
    refarar1.Append(refar1)
    refarar2.Append(refar2)
 
#Get the number of curves stored in the ReferenceArAr.
refsize = refarar1.Size
 
#Loft pairs of curves together for a segmented surface.
for i in range(0,refsize-1):
    loftar = ReferenceArrayArray()
    loftar.Append(refarar1[i])
    loftar.Append(refarar2[i+1])
 
    doc.FamilyCreate.NewLoftForm(True, loftar)
 
t.Commit()
 
__window__.Close()

License

The code and components on this page are free software: you can redistribute them and/or modify them under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

http://www.gnu.org/licenses/

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License