Author Topic: Some more curves  (Read 2650 times)

0 Members and 1 Guest are viewing this topic.

Offline (gile)

  • C#
  • *
  • Posts: 87
  • Karma: +8/-0
  • Gender: Male
    • prefered language: F
    • Prog expertise: Good
    • View Profile
Some more curves
« on: October 24, 2012, 02:50:13 PM »
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:
Code: [Select]
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.

Code: [Select]
el = Ellipse.FromRadii(30..80..5, 30);



Parabolas with decremented chords and incrmented sagittas

Code: [Select]
parabs = Parabola.FromChordSagitta(200..100..-10, 20..120..10, 19, false);


 
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.

Code: [Select]
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);



 

Offline (gile)

  • C#
  • *
  • Posts: 87
  • Karma: +8/-0
  • Gender: Male
    • prefered language: F
    • Prog expertise: Good
    • View Profile
Re: Some more curves
« Reply #1 on: November 01, 2012, 07:42:45 PM »
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

Code: [Select]
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);
    }
}