Archive for the ‘Parametric Design’ Category

Bezier Curves, algorithm of de Casteljau

Sunday, November 1st, 2009

I started reading on Curve models and geometries, different types of Spline algorithms. This is a first attempt to generate Bezier curvers using the algorithm of de Casteljau. The script uses a selected polyline as the control polygon of the curve. The Bezier is created in several steps to illustrate the process. It runs under Microstation MVBA.

Bezier curve of degree 3

Bezier curve of degree 3

Bezier curve of degree 4

Bezier curve of degree 4

Bezier curve of degree 5

Bezier curve of degree 5

Bezier curve of degree 8

Bezier curve of degree 8

‘Linestring Bezier Approximation after Casteljau’s algorithm
‘Sebastian Gmelin
’24.10.2009

‘draw and select linestring and run script

Const cDiv As Long = 5 ‘subdivision at which guidlines are drawn and a copy of the drawing set is created
Const div As Long = 50 ‘subdivision between cDiv for bezier spline points (total subdivision = cDiv * div)

Dim cPoints() As Point3d
Dim bPoints() As Point3d
Dim cSize As Point3d
Dim cLine As Element
Private Sub ScanDesignFile()
‘scan active designfile for selected linestrings
    Dim oElEnum As ElementEnumerator
    Dim oElem As Element

    ‘get collection of selected elements
    Set oElEnum = ActiveModelReference.GetSelectedElements
    ActiveModelReference.UnselectAllElements
   
    ‘go through selection set
    While oElEnum.MoveNext
        Set oElem = oElEnum.Current
        ‘check if active element is linestring
        If (oElem.IsVertexList) Then
            Debug.Print (“Linestring”)
            cPoints = oElem.AsVertexList.GetVertices ‘save collection of vertices
            Set cLine = oElem
        End If
    Wend
End Sub

Private Sub getSize()
‘get linestring size for element copies offset

Dim i As Long
Dim min As Point3d
Dim max As Point3d
Dim lineString As Element

    min = Point3dFromXYZ(1E+17, 1E+17, 1E+17)
    max = Point3dFromXYZ(-1E+17, -1E+17, -1E+17)
   
    For i = 0 To UBound(cPoints)
        If cPoints(i).X > max.X Then max.X = cPoints(i).X
        If cPoints(i).Y > max.Y Then max.Y = cPoints(i).Y
        If cPoints(i).Z > max.Z Then max.Z = cPoints(i).Z
        If cPoints(i).X < min.X Then min.X = cPoints(i).X
        If cPoints(i).Y < min.Y Then min.Y = cPoints(i).Y
        If cPoints(i).Z < min.Z Then min.Z = cPoints(i).Z
    Next
   
    cSize = Point3dFromXYZ(0, max.Y – min.Y, 0)
    cSize.Y = cSize.Y * -1.2
   
End Sub

Sub Casteljau()

Dim i As Long
Dim k As Double
Dim p As Long
Dim points() As Point3d ‘last parent point collection
Dim dPoints() As Point3d ‘division points
Dim mPoints() As Point3d ‘points to draw
Dim lineString As Element
Dim color As Long
Dim count As Long
Dim moveCount As Long

ReDim bPoints(0)
bPoints(0) = cPoints(0)
count = 0
moveCount = 0

For k = 1 / (div * cDiv) To 1 Step 1 / (div * cDiv) ‘k is scale factor of divisions
    points = cPoints
    dPoints = cPoints
    color = 48
    ‘calculate divisions
    While UBound(dPoints) > 1
    ‘points is the collection of vertices of the parent linestring
    ‘dPoints is the child linestring at scalefactor k
        For i = 0 To UBound(points) – 1
            dPoints(i) = Point3dAdd(Point3dScale(Point3dSubtract(points(i + 1), points(i)), k), points(i))
        Next i
        ReDim Preserve dPoints(UBound(points) – 1)
        ‘draw guidlines
        If count = div Then
            mPoints = dPoints
            ‘calculate offset
            For p = 0 To UBound(mPoints)
                mPoints(p) = Point3dAdd(mPoints(p), Point3dScale(cSize, moveCount))
            Next
            ‘draw line
            Set lineString = CreateLineElement1(Nothing, mPoints)
            lineString.color = color
            lineString.LineStyle = ActiveDesignFile.LineStyles(3)
            ActiveModelReference.AddElement lineString
            lineString.Redraw
            color = color + 48
        End If
        points = dPoints
    Wend
    count = count + 1
    ‘draw progress of bezier curve
    If count > div Then
        count = 0
        ‘copy control polygon
        Set lineString = ActiveModelReference.CopyElement(cLine)
        Call lineString.Move(Point3dScale(cSize, moveCount))
        ActiveModelReference.AddElement lineString
        lineString.Redraw
        moveCount = moveCount + 1
        ‘calculate offset of beziers pline
        mPoints = bPoints
        For p = 0 To UBound(mPoints)
            mPoints(p) = Point3dAdd(mPoints(p), Point3dScale(cSize, moveCount – 1))
        Next
        ‘draw bezier progress
        Set lineString = CreateLineElement1(Nothing, mPoints)
        lineString.color = 3
        lineString.LineWeight = 2
        ActiveModelReference.AddElement lineString
        lineString.Redraw
    End If
    ‘add calculated division point to collection of bezier points
    ReDim Preserve bPoints(UBound(bPoints) + 1)
    bPoints(UBound(bPoints)) = Point3dAdd(Point3dScale(Point3dSubtract(points(1), points(0)), k), points(0))
Next k

‘draw final bezier curve
mPoints = bPoints
For p = 0 To UBound(mPoints)
    mPoints(p) = Point3dAdd(mPoints(p), Point3dScale(cSize, moveCount – 1))
Next
Set lineString = CreateLineElement1(Nothing, mPoints)
lineString.color = 3
lineString.LineWeight = 2
ActiveModelReference.AddElement lineString
lineString.Redraw

End Sub
Sub Main()

    If ActiveModelReference.AnyElementsSelected Then
        ScanDesignFile
        getSize
        Casteljau
    End If

End Sub

more Bezier curves

more Bezier curves

more Bezier curves

more Bezier curves

more Bezier curves

more Bezier curves

more Bezier curves

more Bezier curves

more Bezier curves

more Bezier curves

Share

Johannes Itten – “Tower of Fire”,parametric model

Wednesday, October 21st, 2009

Having seen a rebuilt of Itten’s “Tower of Fire” at the Bauhaus exhibition, I started swcripting a parametric model of the tower in the spirit of the workshop we’re planning to do next year. The VBA script runs in Microstation and is modified by the following parameters:

  • cSize As Double = edgeLength of the bottom cube
  • cAngle As Double = rotation in plan between each cube
  • cNumber As Long = number of cubes / levels
  • cScale As Double = the bottom radii of the cones equals the diagnal conrner distance by default. This is scaled by cScale parameter
  • uSeg As Long = Number of linear panels on cone
  • vSeg As Long = Number of circular panels on cone
  • cRad As Double = Radius of panel frames

Images of rebuilts of the tower:

Examples of towers using different parameters:
tower of fire 01

tower of fire 01

tower of fire 01 top view

tower of fire 01 top view

tower of fire 02

tower of fire 02

tower of fire 02 top view

tower of fire 02 top view

tower of fire 03

tower of fire 03

tower of fire 03 top view

tower of fire 03 top view

Source code for Microstation MVBA:

‘Draw a “tower of fire”
‘Parametric approach to Johannes Itten’s design
‘Sebastian Gmelin
’19.10.2009

Option Explicit

Const cSize As Double = 60
Const cAngle As Double = 3
Const cNumber As Long = 40
Const cScale As Double = 2
Const uSeg As Long = 10
Const vSeg As Long = 1
Const cRad As Double = 0.05

Public Type cube
    height As Double
    startPoint As Point3d
    endPoint As Point3d
    direction As Point3d
    botVertex(5) As Point3d
    topVertex(5) As Point3d
End Type

Dim cubes() As cube
Sub Main()
    Dim i As Long
    Dim k As Long
    Dim p As Long
    Dim q As Long
    Dim size As Double
    Dim direction As Point3d
    Dim startPoint As Point3d
    Dim endPoint As Point3d
    Dim height As Double
    Dim cOffset As Double
    Dim conePoints(4) As Point3d
    Dim cSpans() As Point2d
   
    Dim cSurface As New BsplineSurface
    Dim cCurves(2) As New BsplineCurve
    Dim isoCurves() As New BsplineCurve
    Dim cPath As New BsplineCurve
       
    Dim line As Element
    Dim coneEdge(2) As Element
    Dim cLine(3) As Element
    Dim cArc As Element
    Dim cSurfElement As BsplineSurfaceElement
    Dim cSpline As BsplineCurveElement
   
    ReDim cubes(cNumber)
    
    size = cSize
    direction = Point3dFromXYZ(1, 0, 0)
    startPoint = Point3dFromXYZ(size / -2, size / 2, 0)
    endPoint = Point3dFromXYZ(size / 2, size / 2, 0)
    height = Point3dDistance(endPoint, startPoint)
   
    For i = 1 To cNumber
        Call createBox(startPoint, endPoint)
       
        cOffset = Atn(cAngle * 3.141 / 180) * height
        height = Point3dDistance(endPoint, startPoint)
       
        ‘store data
        cubes(i).height = height
        cubes(i).startPoint = startPoint
        cubes(i).endPoint = endPoint
        cubes(i).direction = direction
        cubes(i).botVertex(1) = startPoint
        cubes(i).botVertex(2) = endPoint
        cubes(i).botVertex(3) = Point3dSubtract(endPoint, Point3dCrossProduct(Point3dSubtract(endPoint, startPoint), Point3dFromXYZ(0, 0, 1)))
        cubes(i).botVertex(4) = Point3dSubtract(startPoint, Point3dCrossProduct(Point3dSubtract(endPoint, startPoint), Point3dFromXYZ(0, 0, 1)))
        cubes(i).botVertex(0) = cubes(i).botVertex(4)
        cubes(i).botVertex(5) = cubes(i).botVertex(1)
        For k = 0 To 5
            cubes(i).topVertex(k) = cubes(i).botVertex(k)
            cubes(i).topVertex(k).z = cubes(i).botVertex(k).z + height
        Next
       
        ‘draw testpoints
        CadInputQueue.SendCommand “ACTIVE STYLE 1″
       
        Set line = CreateLineElement2(Nothing, cubes(i).botVertex(1), cubes(i).topVertex(3))
        ActiveModelReference.AddElement line
        line.Redraw
       
        Set line = CreateLineElement2(Nothing, cubes(i).botVertex(2), cubes(i).topVertex(4))
        ActiveModelReference.AddElement line
        line.Redraw
       
        Set line = CreateLineElement2(Nothing, cubes(i).botVertex(3), cubes(i).topVertex(1))
        ActiveModelReference.AddElement line
        line.Redraw
       
        Set line = CreateLineElement2(Nothing, cubes(i).botVertex(4), cubes(i).topVertex(2))
        ActiveModelReference.AddElement line
        line.Redraw
       
        ‘change data for next cube
        startPoint = Point3dSubtract(startPoint, Point3dScale(Point3dNormalize(Point3dCrossProduct(direction, Point3dFromXYZ(0, 0, 1))), cOffset))
        endPoint = Point3dSubtract(endPoint, Point3dScale(Point3dNormalize(direction), cOffset))
        direction = Point3dSubtract(endPoint, startPoint)
        startPoint.z = startPoint.z + height
        endPoint.z = endPoint.z + height
    Next
       
    For i = 2 To cNumber
        For k = 1 To 4
            SetCExpressionValue “tcb->symbology.color”, 0, “MGDSHOOK”
            CadInputQueue.SendCommand “ACTIVE STYLE 2″
            conePoints(0) = cubes(i).topVertex(k)
            conePoints(1) = cubes(i – 1).topVertex(k)
            conePoints(2) = cubes(i).topVertex(k + 1)
            conePoints(3) = Point3dScale(Point3dAdd(conePoints(1), conePoints(2)), 0.5)
            conePoints(4) = Point3dAdd(conePoints(3), Point3dScale(Point3dNormalize(Point3dCrossProduct(Point3dSubtract(conePoints(3), conePoints(0)), Point3dSubtract(conePoints(2), conePoints(1)))), cubes(i).height * cScale))
            
            Set coneEdge(1) = CreateLineElement2(Nothing, cubes(i – 1).topVertex(k), cubes(i).topVertex(k))
            ActiveModelReference.AddElement coneEdge(1)
            coneEdge(1).Redraw
            Set coneEdge(2) = CreateLineElement2(Nothing, cubes(i).topVertex(k), cubes(i).topVertex(k + 1))
            ActiveModelReference.AddElement coneEdge(2)
            coneEdge(2).Redraw
           
            Set cLine(1) = CreateLineElement2(Nothing, conePoints(1), conePoints(2))
            ActiveModelReference.AddElement cLine(1)
            cLine(1).Redraw
            Set cLine(1) = CreateLineElement2(Nothing, conePoints(0), conePoints(3))
            ActiveModelReference.AddElement cLine(1)
            cLine(1).Redraw
            Set cLine(1) = CreateLineElement2(Nothing, conePoints(3), conePoints(4))
            ActiveModelReference.AddElement cLine(1)
            cLine(1).Redraw
           
            Set cArc = CreateArcElement3(Nothing, conePoints(1), conePoints(4), conePoints(2))
            ActiveModelReference.AddElement cArc
            cArc.Redraw
           
            Call cCurves(0).FromElement(coneEdge(1))
            Call cCurves(1).FromElement(coneEdge(2))
            Call cCurves(2).FromElement(cArc)
           
            SetCExpressionValue “tcb->symbology.color”, k, “MGDSHOOK”
            CadInputQueue.SendCommand “ACTIVE STYLE 0″
            Call cSurface.FromRailsAndSweptSections(cCurves(0), cCurves(1), cCurves(2), Nothing)
            Set cSurfElement = CreateBsplineSurfaceElement1(Nothing, cSurface)
            ActiveModelReference.AddElement cSurfElement
            cSurfElement.Redraw
           
            ‘create Network U
            For q = 0 To uSeg
                isoCurves = cSurface.ExtractIsoparametricCurve(cSpans, q / uSeg, msdBsplineSurfaceU)
                For p = LBound(isoCurves) To UBound(isoCurves)
                    Set cSpline = CreateBsplineCurveElement1(Nothing, isoCurves(p))
                    ActiveModelReference.AddElement cSpline
                    cSpline.Redraw
                    Call createTube(cRad, isoCurves(p))
                Next p
            Next q
           
            ‘create Network V
            For q = 0 To vSeg
                isoCurves = cSurface.ExtractIsoparametricCurve(cSpans, q / vSeg, msdBsplineSurfaceV)
                For p = LBound(isoCurves) To UBound(isoCurves)
                    Set cSpline = CreateBsplineCurveElement1(Nothing, isoCurves(p))
                    ActiveModelReference.AddElement cSpline
                    cSpline.Redraw
                    Call createTube(cRad, isoCurves(p))
                Next p
            Next q
        Next k
    Next i

End Sub
Sub createBox(startPoint As Point3d, endPoint As Point3d)

    CadInputQueue.SendCommand “ACTIVE STYLE 0″
    SetCExpressionValue “tcb->symbology.color”, 0, “MGDSHOOK”
   
‘   Start a command
    CadInputQueue.SendCommand “MODELER BLOCK”

‘   Set a variable associated with a dialog box
    SetCExpressionValue “tcb->ms3DToolSettings.block.axisMode”, 0, “FEATURESOLID”
    SetCExpressionValue “tcb->ms3DToolSettings.block.length.value”, (ActiveModelReference.UORsPerMasterUnit * Abs(Point3dDistance(startPoint, endPoint))), “FEATURESOLID”
    SetCExpressionValue “tcb->ms3DToolSettings.block.width.value”, (ActiveModelReference.UORsPerMasterUnit * Abs(Point3dDistance(startPoint, endPoint))), “FEATURESOLID”
    SetCExpressionValue “tcb->ms3DToolSettings.block.height.value”, (ActiveModelReference.UORsPerMasterUnit * Abs(Point3dDistance(startPoint, endPoint))), “FEATURESOLID”
    SetCExpressionValue “tcb->ms3DToolSettings.block.height.locked”, 0, “FEATURESOLID”
    SetCExpressionValue “tcb->ms3DToolSettings.block.width.locked”, 0, “FEATURESOLID”
    SetCExpressionValue “tcb->ms3DToolSettings.block.length.locked”, 0, “FEATURESOLID”

    CadInputQueue.SendDataPoint startPoint, 1

‘   Send a keyin that can be a command string
    CadInputQueue.SendKeyin “AccuDraw Rotate Top”

    CadInputQueue.SendDataPoint endPoint, 1

    CadInputQueue.SendDataPoint Point3dSubtract(startPoint, Point3dCrossProduct(Point3dSubtract(endPoint, startPoint), Point3dFromXYZ(0, 0, 1))), 1
   
    CadInputQueue.SendDataPoint Point3dAdd(startPoint, Point3dFromXYZ(0, 0, Abs(Point3dDistance(startPoint, endPoint)))), 1

    CadInputQueue.SendCommand “CHOOSE ELEMENT”

    CommandState.StartDefaultCommand
End Sub

Sub createTube(rad As Double, path As BsplineCurve)
    Dim Frame As Matrix3d
    Dim Curvature As Double
    Dim Torsion As Double
    Dim Parameter As Double
    Dim LinearNormal As Point3d
    Dim Normal As Point3d
    Dim cPoint As Point3d
    Dim circ As Element
    Dim Rot As Matrix3d
    Dim line As Element
    Dim x As Point3d
    Dim y As Point3d
    Dim z As Point3d
    Dim startPoint As Point3d
    Dim endPoint As Point3d
   
    Dim cSurface As New BsplineSurface
    Dim cSurfElement As BsplineSurfaceElement
    Dim cSection As New BsplineCurve
       
    endPoint = path.EvaluatePointFrame(Frame, Curvature, Torsion, 1, LinearNormal)
    startPoint = path.EvaluatePointFrame(Frame, Curvature, Torsion, 0, LinearNormal)
    cPoint = startPoint
   
    y = Point3dNormalize(Point3dCrossProduct(Frame.RowY, Frame.RowX))
    z = Point3dNormalize(Frame.RowX)
    x = Point3dNormalize(Point3dCrossProduct(y, z))
   
    Rot = Matrix3dFromPoint3dColumns(x, y, z)
   
    Set line = CreateLineElement2(Nothing, cPoint, Point3dAdd(cPoint, x))
    line.Color = 1
    ActiveModelReference.AddElement line
    line.Redraw
   
    Set line = CreateLineElement2(Nothing, cPoint, Point3dAdd(cPoint, y))
    line.Color = 2
    ActiveModelReference.AddElement line
    line.Redraw
   
    Set line = CreateLineElement2(Nothing, cPoint, Point3dAdd(cPoint, z))
    line.Color = 3
    ActiveModelReference.AddElement line
    line.Redraw
   
    Set circ = CreateEllipseElement2(Nothing, cPoint, rad, rad, Rot)
    ActiveModelReference.AddElement circ
    circ.Redraw
   
    Call cSection.FromElement(circ)
    SetCExpressionValue “tcb->symbology.color”, 6, “MGDSHOOK”
    CadInputQueue.SendCommand “ACTIVE STYLE 0″
    Call cSurface.FromRailAndSweptSection(path, cSection)
    Set cSurfElement = CreateBsplineSurfaceElement1(Nothing, cSurface)
    ActiveModelReference.AddElement cSurfElement
    cSurfElement.Redraw
       
End Sub

Share

Bauhaus exhibition in Berlin

Sunday, October 4th, 2009
091003-bauhaus-exhibit-01
091003-bauhaus-exhibit-01, image from exhibition flyer

While visiting the Bauhaus exhibition with some of the new PhD students, Niels and I came up with the idea of running a parametric design class at the school using a similar education strategy as it was done in the 1920ies at the Bauhaus. As a preparation for a design work, the students will be introduced to the methodology of parametric design and get introductions to different (parametric design) software tools. They then chose a master class – sculpture of painting. They use one or more tools to experiment in either field and design a parametric art object that might be produced with 3d printing technology of laser cutters. During this exercise a design language and working method should be established that is then taken to an architectural design project. In teams of four students, knowledge about different tools will be joined to work on a more complex project.

091004-bauhaus-project
091004-bauhaus-project

 Some Bauhaus projects might actually work as a template for the students as they might be transformed into parametric designs.

091003-bauhaus-exhibit-02
091003-bauhaus-exhibit-02, image from exhibition flyer
091003-bauhaus-exhibit-03
091003-bauhaus-exhibit-03, image from exhibition flyer

Thanks to Jorgen and Carsten for organizing this trip!

Share

sketchup sandbox tool

Sunday, September 27th, 2009

Google sketchup sandbox is a free-form modeler based on a meshed surface. It can be pushed and pulled with a ‘smoove‘ tool. The diameter of the tool can be adjusted numerically. Complex surfaces can be created very intuitively. This is what I had in mind for B-processor. The deformation should then follow material properties.

Share