• Industries
  • Products
  • Buy
  • Services & Support
  • Communities
  • Discussion Groups

    DesignScript

    Reply
    *Expert Elite*
    Posts: 1,640
    Registered: ‎04-29-2006

    Some more curves

    289 Views, 4 Replies
    10-24-2012 03:26 AM

    Hi,

    DesignScript is relatively poor in native curves (Line, Arc, Circle and BSplineCurve).
    I thought it might be interesting to define some others.
    I tried to do this as classes with constructors, these classes may be required to evolve with the addition of new features.
    The
    generated curves are spline whose control points or smoothing are calculated from the equations of these curves.

     

    The Catenary, Ellipse, EllpticalArc and Parabola classes:

    import("ProtoGeometry.dll");
    import("Math.dll");
        
    class Catenary
    {
        Curve : Curve;
        Chord : double;
        Param : double;
        Sagitta : double;
        Length : double;
        
        def argCosh(x : double)
        {
            return = Math.Log(x + Math.Sqrt(x * x - 1));
        }

        constructor FromChordParam(chord : double, param : double, numPts : int)
        {
            Chord = chord;
            Param = param;
            Sagitta = param * Math.Cosh(chord / (2 * param)) - param;
            Length = 2 * param * Math.Sinh(chord / (2 * param));
            x = chord / -2..chord / 2..#numPts;
            y = param * Math.Cosh(x / param);
            Curve = BSplineCurve.ByPoints(Point.ByCoordinates(x, y, 0));
        }
        
        constructor FromLenthSagitta(length : double, sagitta : double, numPts : int)
        {
            Length = length;
            Sagitta = sagitta;
            Param = (length * length - 4 * sagitta * sagitta) / (8 * sagitta);
            Chord = 2 * Param * argCosh((sagitta + Param) / Param);
            x = Chord / -2..Chord / 2..#numPts;
            y = Param * Math.Cosh(x / Param);
            Curve = BSplineCurve.ByPoints(Point.ByCoordinates(x, y, 0));
        }
    } class Ellipse { Curve : Curve; constructor FromRadii(majRadius : double, minRadius : double) { Curve = Circle.ByCenterPointRadius(Point.ByCoordinates(0, 0, 0), 1) .Transform(CoordinateSystem.WCS, CoordinateSystem.Identity().Scale(majRadius, minRadius, 1)); } } class EllipticalArc { Curve : Curve; constructor FromRadii(majRadius : double, minRadius : double, startAngle : double, sweepAngle : double) { endAngle = startAngle + sweepAngle; startParam = Math.Atan(majRadius * Math.Tan(startAngle) / minRadius); endParam = Math.Atan(majRadius * Math.Tan(endAngle) / minRadius); [Imperative] { if (startAngle == 0 || startAngle == 90 || startAngle == 180 || startAngle == 270 || startAngle == 360) startParam = startAngle; else if (startAngle > 90 && startAngle < 270) startParam = startParam + 180; if (endAngle == 0 || endAngle == 90 || endAngle == 180 || endAngle == 270 || endAngle == 360) endParam = endAngle; else if (endAngle > 90 && endAngle < 270) endParam = endParam + 180; if (endParam <= startParam) endParam = endParam + 360; } Curve = Arc.ByCenterPointRadiusAngle(Point.ByCoordinates(0, 0, 0), 1, startParam, endParam - startParam, Vector.ByCoordinates(0, 0, 1)) .Transform(CoordinateSystem.WCS, CoordinateSystem.Identity().Scale(majRadius, minRadius, 1)); } } class Parabola
    {
        Curve : Curve;
        Focus : Point;
        
        constructor FromChordSagitta(chord : double, sagitta : double, numPts : int, focusVisible : bool)
        {
            a = 4 * sagitta / (chord * chord);
            Focus = Point.ByCoordinates(0, 1 / (4 * a), 0).SetVisibility(focusVisible);
            x = chord / - 2..chord / 2..#numPts;
            y = a * x * x;
            Curve = BSplineCurve.ByPoints(Point.ByCoordinates(x, y, 0));
        }
    }

     

    Using examples

     

    Ellipses with incremented major axis.

    el = Ellipse.FromRadii(30..80..5, 30);

     Ellipse.png

     

    Parabolas with decremented chords and incrmented sagittas.

    parabs = Parabola.FromChordSagitta(200..100..-10, 20..120..10, 19, false);

     Parabola.png

     

    Catenaries with incremented params.

    Each curve is moved so that start and end point lies ont the X axis. This is done using the Param and Sagitta properties of the Catenary instance.

    def catenar(chord : double, param : double, numPts : int)
    {
        cat = Catenary.FromChordParam(chord, param, numPts);
        return = cat.Curve.Translate(0, -cat.Param - cat.Sagitta, 0);
    }
    
    cats = catenar(160, 35..75..#10, 19);

     Catenary.png

     

    Gilles Chanteau
    Please use plain text.
    Member
    Posts: 5
    Registered: ‎10-20-2012

    Re: Some more curves

    10-24-2012 06:08 AM in reply to: _gile

    Thanks!

     

    These definitions are very useful.

    Please use plain text.
    Active Member
    Posts: 7
    Registered: ‎09-26-2012

    Re: Some more curves

    10-30-2012 04:29 PM in reply to: _gile

    This is great! How did you find writing your own classes? Any surprises?

     

    Luke

    Please use plain text.
    *Expert Elite*
    Posts: 1,640
    Registered: ‎04-29-2006

    Re: Some more curves

    10-31-2012 02:26 PM in reply to: luke

    Thanks Luke.

     

    I found an example of class in the tutorial and try to build my own ones.

    Gilles Chanteau
    Please use plain text.
    *Expert Elite*
    Posts: 1,640
    Registered: ‎04-29-2006

    Re: Some more curves

    11-01-2012 11:37 AM in reply to: _gile

    One more: a cylindrical helix.

    The constructor arguments are:

    • the radius
    • the total height
    • the total angle, if the input is negative the helix turns clockwise
    import("ProtoGeometry.dll");
    import("Math.dll");
    
    class Helix
    {
        Curve : Curve;
        constructor FromRadiusHeightAngle(radius : double, height : double, totalAngle : double)
        {
            pi = 3.141592653589793;
            numPts = Math.Abs(Math.Round(totalAngle / 15)) + 1;
            step = height / (numPts - 1);
            ccw = Math.Sign(totalAngle);
            tanZ = (180 * height) / (pi * totalAngle * radius);
            startTan = Vector.ByCoordinates(0, ccw, ccw * tanZ);
            endTan = Vector.ByCoordinates(ccw * -Math.Sin(totalAngle), ccw * Math.Cos(totalAngle), ccw * tanZ);
            x = radius * Math.Cos(0 .. totalAngle .. #numPts);
            y = radius * Math.Sin(0 .. totalAngle .. #numPts);
            z = step * (0 .. numPts);
            Curve = BSplineCurve.ByPoints(Point.ByCoordinates(x, y, z), startTan, endTan);
        }
    }

     

     

    Gilles Chanteau
    Please use plain text.