/// <summary> /// The spiral of Theodorus is a spiral composed of contiguous right triangles /// </summary> /// <param name="numberRot">Determines the number of turns in the spiral</param> /// <search>square root,einstein,pythagorean</search> public static NurbsCurve Theodorus(int numberRot = 100) { if (numberRot == 0) { throw new ArgumentException("The angle value can't be 0.", "angle"); } if (numberRot < 0) { numberRot = numberRot * -1; } var pts = new List <Point>(); double radius = 1; double currAngle = 0; for (int i = 1; i <= numberRot; ++i) { radius = Math.Sqrt(i); double xVal = radius * Math.Cos(currAngle); double yVal = radius * Math.Sin(currAngle); pts.Add(Point.ByCoordinates(xVal, yVal, 0)); currAngle = currAngle + Math.Atan(1 / Math.Sqrt(i)); } return(NurbsCurve.ByControlPoints(pts, 1, false)); }
public void NurbsCurve_Basic() { var pts = new[] { Point.ByCoordinates(10, 2, 3) , Point.ByCoordinates(0, 2, 2) , Point.ByCoordinates(10, 4, 8) , Point.ByCoordinates(10, 2, 8) , Point.ByCoordinates(5, 5, 5) }; var bspline = NurbsCurve.ByControlPoints(pts, 3); var revitCurve = bspline.ToRevitType(); Assert.NotNull(revitCurve); Assert.IsAssignableFrom <Autodesk.Revit.DB.NurbSpline>(revitCurve); var revitSpline = (Autodesk.Revit.DB.NurbSpline)revitCurve; Assert.AreEqual(bspline.Degree, revitSpline.Degree); Assert.AreEqual(bspline.ControlPoints().Count(), revitSpline.CtrlPoints.Count); // ClosestPointTo fails in ProtoGeometry var tessPts = revitSpline.Tessellate(); //assert the tesselation is very close to original curve //what's the best tolerance to use here? foreach (var pt in tessPts) { var closestPt = bspline.GetClosestPoint(pt.ToPoint()); Assert.Less(closestPt.DistanceTo(pt.ToPoint()), 1e-6); } }
public void ByPointsOnCurve_ValidInput() { // create spline var pts = new Autodesk.DesignScript.Geometry.Point[] { Point.ByCoordinates(0, 0, 0), Point.ByCoordinates(1, 0, 0), Point.ByCoordinates(3, 0, 0), Point.ByCoordinates(10, 0, 0), Point.ByCoordinates(12, 0, 0), }; var spline = NurbsCurve.ByControlPoints(pts, 3); Assert.NotNull(spline); // build model curve from spline var modCurve = ModelCurve.ByCurve(spline); Assert.NotNull(modCurve); // obtain the family from the document var fs = FamilySymbol.ByName("3PointAC"); // build the AC var parms = new double[] { 0, 0.5, 1 }; var ac = AdaptiveComponent.ByParametersOnCurveReference(parms, modCurve.ElementCurveReference, fs); Assert.NotNull(ac); }
public void NurbsCurve_Basic() { var pts = new[] { Point.ByCoordinates(10, 2, 3) , Point.ByCoordinates(0, 2, 2) , Point.ByCoordinates(10, 4, 8) , Point.ByCoordinates(10, 2, 8) , Point.ByCoordinates(5, 5, 5) }; var bspline = NurbsCurve.ByControlPoints(pts, 3); var revitCurve = bspline.ToRevitType(false); Assert.NotNull(revitCurve); Assert.IsAssignableFrom <Autodesk.Revit.DB.NurbSpline>(revitCurve); var revitSpline = (Autodesk.Revit.DB.NurbSpline)revitCurve; Assert.AreEqual(bspline.Degree, revitSpline.Degree); Assert.AreEqual(bspline.ControlPoints().Count(), revitSpline.CtrlPoints.Count); var tessPts = revitSpline.Tessellate().Select(x => x.ToPoint(false)); //assert the tesselation is very close to original curve foreach (var pt in tessPts) { var closestPt = bspline.ClosestPointTo(pt); Assert.Less(closestPt.DistanceTo(pt), 1e-6); } }
public void Points() { // create spline var pts = new[] { Point.ByCoordinates(0, 0, 0), Point.ByCoordinates(1, 0, 0), Point.ByCoordinates(3, 0, 0), Point.ByCoordinates(10, 0, 0), Point.ByCoordinates(12, 0, 0) }; var spline = NurbsCurve.ByControlPoints(pts, 3); Assert.NotNull(spline); // build model curve from spline var modCurve = ModelCurve.ByCurve(spline); Assert.NotNull(modCurve); // build dividedPath var divPath = DividedPath.ByCurveAndDivisions(modCurve.ElementCurveReference, 5); Assert.NotNull(divPath); foreach (var pt in divPath.Points) { Assert.IsTrue(pts.Any(x => x.ShouldBeApproximately(pt))); } }
public void ByCurveAndEqualDivisions_ValidArgs() { // create spline var pts = new[] { Point.ByCoordinates(0, 0, 0), Point.ByCoordinates(1, 0, 0), Point.ByCoordinates(3, 0, 0), Point.ByCoordinates(10, 0, 0), Point.ByCoordinates(12, 0, 0) }; var spline = NurbsCurve.ByControlPoints(pts, 3); Assert.NotNull(spline); // build model curve from spline var modCurve = ModelCurve.ByCurve(spline); Assert.NotNull(modCurve); // build dividedPath var divPath = DividedPath.ByCurveAndDivisions(modCurve.ElementCurveReference, 5); Assert.NotNull(divPath); }
/// <summary> /// A golden spiral is a logarithmic spiral whose growth factor is φ, the golden ratio. /// </summary> /// <param name="angle">360 completes 1 circulation</param> /// <search>golden,fibonacci</search> public static NurbsCurve Golden(double angle = 720) { if (angle == 0.0) { throw new ArgumentException("The angle and scale values can't be 0."); } angle = (angle < 0.0) ? -1 * angle : angle; int numPts = 1000; var pts = new List <Point>(); double b = Math.Log(goldenRatio()) / (Math.PI / 2); double c = Math.Pow(Math.E, b); angle = degToRad(angle); for (int i = 0; i < numPts; ++i) { double currAngle = (double)i / 1000.0 * angle; double radius = Math.Pow(c, currAngle); double xVal = Math.Cos(currAngle) * Math.Pow(c, currAngle); double yVal = Math.Sin(currAngle) * Math.Pow(c, currAngle); pts.Add(Point.ByCoordinates(xVal, yVal, 0)); } return(NurbsCurve.ByControlPoints(pts)); }
public static List <Curve> MorphTo(this Curve curve1, Curve curve2, int numberOfLines, int precision = 10, double offset = 0) { numberOfLines++; Surface virtualSurface = Surface.ByLoft(new List <Curve>() { curve1, curve2 }); Vector direction = virtualSurface.NormalAtParameter(0.5, 0.5); List <Curve> curves = new List <Curve>(); // Divide both curves using the precision factor Point[] pointsCurve1 = curve1.PointDivide(precision); Point[] pointsCurve2 = curve2.PointDivide(precision); // Create a Matrix for the morphed points Point[][] points = new Point[precision + 1][]; // If the Curves are in different directions, flip them. if (pointsCurve1[0].DistanceTo(pointsCurve2[pointsCurve2.Length - 1]) < pointsCurve1[0].DistanceTo(pointsCurve2[0])) { Array.Reverse(pointsCurve2); } // Draw construction lines between the two curves using the division points for (int i = 0; i < pointsCurve1.Length; i++) { Line line = Line.ByStartPointEndPoint(pointsCurve1[i], pointsCurve2[i]); // Divide the construction line into the number of curves to create // Add the divsion points to the matrix points[i] = line.PointDivide(numberOfLines); } // Create an empty Array holding the pointWeights double[] pointWeights = new double[numberOfLines]; // Flip the Matrix to create new curves from Point[][] transposedPoints = points.TransposeRowsAndColumns(); // Create Curves from the Matrix for (int i = 1; i < transposedPoints.Length - 1; i++) { NurbsCurve curve = NurbsCurve.ByControlPoints(transposedPoints[i].ToList()); Curve curveToSegment = (offset != 0) ? (Curve)curve.Translate(direction, offset) : curve; curves.Add(curveToSegment); } return(curves); }
public void ByPointsOnCurve_ProducesValidAdaptiveComponentAndLocations() { // create spline var pts = new Autodesk.DesignScript.Geometry.Point[] { Point.ByCoordinates(0, 0, 0), Point.ByCoordinates(1, 0, 0), Point.ByCoordinates(3, 0, 0), Point.ByCoordinates(10, 0, 0), Point.ByCoordinates(12, 0, 0), }; var spline = NurbsCurve.ByControlPoints(pts, 3); Assert.NotNull(spline); // build model curve from spline var modCurve = ModelCurve.ByCurve(spline); Assert.NotNull(modCurve); // obtain the family from the document var ft = FamilyType.ByName("3PointAC"); // build the AC var parms = new double[] { 0, 0.5, 1 }; var ac = AdaptiveComponent.ByParametersOnCurveReference(parms, modCurve.ElementCurveReference, ft); // with unit conversion foreach (var pt in ac.Locations) { spline.DistanceTo(pt).ShouldBeApproximately(0); } // without unit conversion var unconvertedPoints = GetInternalPoints((FamilyInstance)ac.InternalElement); foreach (var pt in unconvertedPoints) { spline.DistanceTo(pt.ToPoint()).ShouldBeApproximately(0); } Assert.NotNull(ac); }
/// <summary> /// Breaks the continous spiral into a series of straight lines /// </summary> /// <param name="spiral">The spiral to break</param> /// <param name="numBreaks">The number of lines to generate</param> /// <search>break,divide</search> public static NurbsCurve getBrokenSpiral(Curve spiral, int numBreaks = 100) { if (numBreaks == 0) { throw new ArgumentException("The numPts needs to be non-zero positive integer"); } numBreaks = (int)Math.Abs(numBreaks); var pts = new List <Point>(); for (int i = 0; i <= numBreaks; ++i) { pts.Add(spiral.PointAtParameter((double)i / (double)numBreaks)); } return(NurbsCurve.ByControlPoints(pts, 1, false)); }
public static void CanDoSimpleLoft() { var points0 = new Point[10]; var points1 = new Point[10]; for (int i = 0; i < 10; ++i) { points0[i] = Point.ByCoordinates(i, 0, 0); points1[i] = Point.ByCoordinates(i, 10, 10); } var crv0 = NurbsCurve.ByControlPoints(points0); var crv1 = NurbsCurve.ByControlPoints(points1); var srf = Surface.ByLoft(new[] { crv0, crv1 }); Assert.NotNull(srf); Console.WriteLine(srf.PointAtParameter(0.5, 0.5)); }
public void ToRevitType_ExtensionMethod_DoesExpectedUnitConversion() { // testing var pts = new[] { Point.ByCoordinates(10, 2, 3) , Point.ByCoordinates(0, 2, 2) , Point.ByCoordinates(10, 4, 8) , Point.ByCoordinates(10, 2, 8) , Point.ByCoordinates(5, 5, 5) }; var bspline = NurbsCurve.ByControlPoints(pts, 3); // do scaling for check var metersToFeet = 1 / 0.3048; var bsplineScaled = (NurbsCurve)bspline.Scale(metersToFeet); // by default, performs conversion var revitCurve = bspline.ToRevitType(); Assert.NotNull(revitCurve); Assert.IsAssignableFrom <Autodesk.Revit.DB.NurbSpline>(revitCurve); var revitSpline = (Autodesk.Revit.DB.NurbSpline)revitCurve; Assert.AreEqual(bsplineScaled.Degree, revitSpline.Degree); Assert.AreEqual(bsplineScaled.ControlPoints().Count(), revitSpline.CtrlPoints.Count); // We tesselate but not convert units. We are trying to find out if // ToRevitType did the conversion properly by comparing to a scaled // version of the original bspline (bsplineScaled) var tessPts = revitSpline.Tessellate().Select(x => x.ToPoint(false)); //assert the tesselation is very close to original curve foreach (var pt in tessPts) { var closestPt = bsplineScaled.ClosestPointTo(pt); Assert.Less(closestPt.DistanceTo(pt), 1e-6); } }
internal static Curve CurveFromMfnNurbsCurveFromDag(MDagPath dagPath, MSpace.Space space) { Point3DCollection controlVertices; List <double> weights, knots; int degree; bool closed, rational; decomposeMayaCurve(dagPath, space, out controlVertices, out weights, out knots, out degree, out closed, out rational); // var controlPoints = new List<Point>(controlVertices.Count); var curvePoints = new PointList(controlVertices.Count); if (MGlobal.isYAxisUp) { curvePoints.AddRange(controlVertices.Select(cv => Point.ByCoordinates(cv.X, -cv.Z, cv.Y))); } else { curvePoints.AddRange(controlVertices.Select(cv => Point.ByCoordinates(cv.X, cv.Y, cv.Z))); } Curve theCurve; if (closed) { theCurve = NurbsCurve.ByControlPoints(curvePoints, degree, true); } else { theCurve = NurbsCurve.ByControlPointsWeightsKnots(curvePoints, weights.ToArray(), knots.ToArray(), degree); } curvePoints.Dispose(); return(theCurve); }
public void ByCurveAndEqualDivisions_InvalidDivisions() { // create spline var pts = new[] { Point.ByCoordinates(0, 0, 0), Point.ByCoordinates(1, 0, 0), Point.ByCoordinates(3, 0, 0), Point.ByCoordinates(10, 0, 0), Point.ByCoordinates(12, 0, 0) }; var spline = NurbsCurve.ByControlPoints(pts, 3); Assert.NotNull(spline); // build model curve from spline var modCurve = ModelCurve.ByCurve(spline); Assert.NotNull(modCurve); // build dividedPath Assert.Throws(typeof(Exception), () => DividedPath.ByCurveAndDivisions(modCurve.ElementCurveReference, 0)); }
public void Points() { // create spline var pts = new[] { Point.ByCoordinates(0, 0, 0), Point.ByCoordinates(1, 0, 0), Point.ByCoordinates(3, 0, 0), Point.ByCoordinates(10, 0, 0), Point.ByCoordinates(12, 0, 0) }; var spline = NurbsCurve.ByControlPoints(pts, 3); Assert.NotNull(spline); // build model curve from spline var modCurve = ModelCurve.ByCurve(spline); Assert.NotNull(modCurve); // build dividedPath var divPath = DividedPath.ByCurveAndDivisions(modCurve.ElementCurveReference, 5); Assert.NotNull(divPath); var divPathPts = divPath.Points; Assert.AreEqual(5, divPathPts.Count()); foreach (var pt in divPathPts) { // all of the points should be along the curve spline.DistanceTo(pt).ShouldBeApproximately(0); } }
public static void ToMaya(Curve CurveToSend, string name) { NurbsCurve ctsAsNurb = null; if (CurveToSend is Rectangle) { Rectangle rec = (Rectangle)CurveToSend; ctsAsNurb = NurbsCurve.ByControlPoints(rec.Points, 1, true); } else if (CurveToSend is Polygon) { Polygon rec = (Polygon)CurveToSend; ctsAsNurb = NurbsCurve.ByControlPoints(rec.Points, 1, true); } else { ctsAsNurb = CurveToSend.ToNurbsCurve(); } var ncd = new MFnNurbsCurveData(); MFnNurbsCurveForm mfnform; if (ctsAsNurb.IsClosed) { mfnform = MFnNurbsCurveForm.kClosed; } else { mfnform = MFnNurbsCurveForm.kOpen; } var mayaCurve = new MFnNurbsCurve(); var vtxs = new MPointArray(); var cvs = ctsAsNurb.ControlPoints(); var yUp = MGlobal.isYAxisUp; if (yUp) { foreach (var cv in cvs) { var pt = new MPoint(cv.X, cv.Z, -cv.Y); vtxs.Add(pt); //pt.Dispose(); } } else { foreach (var cv in cvs) { var pt = new MPoint(cv.X, cv.Y, cv.Z); vtxs.Add(pt); //pt.Dispose(); } } var knots = ctsAsNurb.Knots(); var crvKnots = new MDoubleArray(knots); crvKnots.RemoveAt(0); crvKnots.RemoveAt(crvKnots.Count - 1); MDagPath node = null; var nodeExists = false; Task checkNode = null; Task deleteNode = null; try { node = DMInterop.getDagNode(name); nodeExists = true; } catch (Exception) { nodeExists = false; } MObject obj; if (nodeExists) { MDagPath nodeShape = node; nodeShape.extendToShape(); var modifyCrv = new MDGModifier(); mayaCurve = new MFnNurbsCurve(nodeShape); try { MFnNurbsCurveData dataCreator = new MFnNurbsCurveData(); MObject outCurveData = dataCreator.create(); var span = (vtxs.Count - ctsAsNurb.Degree); string rblCmd = $"rebuildCurve -rt 0 -s {span} -d {ctsAsNurb.Degree} {name}"; if (mayaCurve.numCVs != vtxs.Count || mayaCurve.degree != ctsAsNurb.Degree) { MGlobal.executeCommand(rblCmd); } mayaCurve.setCVs(vtxs); mayaCurve.setKnots(crvKnots, 0, crvKnots.length - 1); mayaCurve.updateCurve(); modifyCrv.doIt(); if (CurveToSend.GetType() == typeof(Circle)) { span = 8; rblCmd = $"rebuildCurve -rt 0 -s {span} {name}"; MGlobal.executeCommand(rblCmd); } } catch (Exception e) { MGlobal.displayWarning(e.Message); } } else { obj = mayaCurve.create(vtxs, crvKnots, (uint)ctsAsNurb.Degree, (MFnNurbsCurve.Form)mfnform, false, ctsAsNurb.IsRational); MFnDependencyNode nodeFn = new MFnDagNode(obj); nodeFn.setName(name); } }
/// <summary> /// Returns the list of Dynamo curves that defines the Alignment. /// </summary> /// <returns>A list of lines and arcs that decribe the Alignment.</returns> /// <remarks>The tool returns only lines and arcs.</remarks> public IList <Curve> GetCurves() { Utils.Log("Alignment.GetCurves Started..."); IList <Curve> output = new List <Curve>(); foreach (AeccAlignmentEntity e in this._entities) { switch (e.Type) { case AeccAlignmentEntityType.aeccTangent: { AeccAlignmentTangent a = e as AeccAlignmentTangent; output.Add(Line.ByStartPointEndPoint( Point.ByCoordinates(a.StartEasting, a.StartNorthing), Point.ByCoordinates(a.EndEasting, a.EndNorthing))); break; } case AeccAlignmentEntityType.aeccArc: { AeccAlignmentArc a = e as AeccAlignmentArc; Arc arc = null; if (!a.Clockwise) { arc = Arc.ByCenterPointStartPointEndPoint( Point.ByCoordinates(a.CenterEasting, a.CenterNorthing), Point.ByCoordinates(a.StartEasting, a.StartNorthing), Point.ByCoordinates(a.EndEasting, a.EndNorthing)); } else { arc = Arc.ByCenterPointStartPointEndPoint( Point.ByCoordinates(a.CenterEasting, a.CenterNorthing), Point.ByCoordinates(a.EndEasting, a.EndNorthing), Point.ByCoordinates(a.StartEasting, a.StartNorthing)); } output.Add(arc); //var p1 = a.PassThroughPoint1; //var p2 = a.PassThroughPoint2; //var p3 = a.PassThroughPoint3; //output.Add(Arc.ByThreePoints(Point.ByCoordinates(p1.X, p1.Y), // Point.ByCoordinates(p2.X, p2.Y), // Point.ByCoordinates(p3.X, p3.Y))); break; } case AeccAlignmentEntityType.aeccSpiralCurveSpiralGroup: { AeccAlignmentSCSGroup a = e as AeccAlignmentSCSGroup; AeccAlignmentEntity before = this._entities.Item(e.EntityBefore); AeccAlignmentEntity after = this._entities.Item(e.EntityAfter); Curve beforeCurve = null; Curve afterCurve = null; if (before.Type == AeccAlignmentEntityType.aeccTangent) { AeccAlignmentTangent b = before as AeccAlignmentTangent; beforeCurve = Line.ByStartPointEndPoint( Point.ByCoordinates(b.StartEasting, b.StartNorthing), Point.ByCoordinates(b.EndEasting, b.EndNorthing)); } else if (before.Type == AeccAlignmentEntityType.aeccArc) { AeccAlignmentArc b = before as AeccAlignmentArc; beforeCurve = Arc.ByCenterPointStartPointEndPoint( Point.ByCoordinates(b.CenterEasting, b.CenterNorthing), Point.ByCoordinates(b.StartEasting, b.StartNorthing), Point.ByCoordinates(b.EndEasting, b.EndNorthing)); } if (after.Type == AeccAlignmentEntityType.aeccTangent) { AeccAlignmentTangent b = after as AeccAlignmentTangent; afterCurve = Line.ByStartPointEndPoint( Point.ByCoordinates(b.StartEasting, b.StartNorthing), Point.ByCoordinates(b.EndEasting, b.EndNorthing)); } else if (after.Type == AeccAlignmentEntityType.aeccArc) { AeccAlignmentArc b = after as AeccAlignmentArc; afterCurve = Arc.ByCenterPointStartPointEndPoint( Point.ByCoordinates(b.CenterEasting, b.CenterNorthing), Point.ByCoordinates(b.StartEasting, b.StartNorthing), Point.ByCoordinates(b.EndEasting, b.EndNorthing)); } if (afterCurve != null && beforeCurve != null) { output.Add(Curve.ByBlendBetweenCurves(beforeCurve, afterCurve)); } // Andrew Milford wrote the code for the spirals using Fourier approximation // Get some parameters int entCnt = a.SubEntityCount; for (int i = 0; i < entCnt; i++) { AeccAlignmentEntity subEnt = a.SubEntity(i); AeccAlignmentEntityType alignType = subEnt.Type; switch (alignType) { case AeccAlignmentEntityType.aeccTangent: break; case AeccAlignmentEntityType.aeccArc: AeccAlignmentArc arc = subEnt as AeccAlignmentArc; Arc dArc = null; if (!arc.Clockwise) { dArc = Arc.ByCenterPointStartPointEndPoint( Point.ByCoordinates(arc.CenterEasting, arc.CenterNorthing), Point.ByCoordinates(arc.StartEasting, arc.StartNorthing), Point.ByCoordinates(arc.EndEasting, arc.EndNorthing)); } else { dArc = Arc.ByCenterPointStartPointEndPoint( Point.ByCoordinates(arc.CenterEasting, arc.CenterNorthing), Point.ByCoordinates(arc.EndEasting, arc.EndNorthing), Point.ByCoordinates(arc.StartEasting, arc.StartNorthing)); } output.Add(dArc); break; case AeccAlignmentEntityType.aeccSpiral: // calculate the spiral intervals AeccAlignmentSpiral s = subEnt as AeccAlignmentSpiral; double radIn = s.RadiusIn; double radOut = s.RadiusOut; double length = s.Length; AeccAlignmentSpiralDirectionType dir = s.Direction; // Identify the spiral is the start or end bool isStart = true; double radius; if (Double.IsInfinity(radIn)) { // Start Spiral radius = radOut; } else { // End Spiral radius = radIn; isStart = false; } double A = s.A; // Flatness of spiral double RL = radius * length; //double A = Math.Sqrt(radius * length); List <Point> pts = new List <Point>(); double n = 0; double interval = 2; // 2 meters intervals TODO what if the curve is shorter than 2 meters? int num = Convert.ToInt32(Math.Ceiling(length / interval)); double step = length / num; double dirStart = s.StartDirection; double dirEnd = s.EndDirection; Point ptPI = Point.ByCoordinates(s.PIEasting, s.PINorthing, 0); Point ptStart = Point.ByCoordinates(s.StartEasting, s.StartNorthing, 0); Point ptEnd = Point.ByCoordinates(s.EndEasting, s.EndNorthing, 0); Point pt; double angRot; /* * Paolo Serra - Implementation of Fourier's Transform for the clothoid for a given number of terms * x = Sum[(-1)^t * n ^(4*t+1) / ((2*t)!*(4*t+1)*(2*RL)^(2*t))] for t = 0 -> N * y = Sum[(-1)^t * n ^(4*t+3) / ((2^t + 1)!*(4*t+3)*(2*RL)^(2*t + 1))] for t = 0 -> N */ for (int j = 0; j <= num; j++) { double x = 0; double y = 0; for (int t = 0; t < 8; t++) // first 8 terms of the transform { x += Math.Pow(-1, t) * Math.Pow(n, 4 * t + 1) / (Factorial(2 * t) * (4 * t + 1) * Math.Pow(2 * RL, 2 * t)); y += Math.Pow(-1, t) * Math.Pow(n, 4 * t + 3) / (Factorial(2 * t + 1) * (4 * t + 3) * Math.Pow(2 * RL, 2 * t + 1)); } //double x = n - ((Math.Pow(n, 5)) / (40 * Math.Pow(RL, 2))) + ((Math.Pow(n, 9)) / (3456 * Math.Pow(RL, 4))) - ((Math.Pow(n, 13)) / (599040 * Math.Pow(RL, 6))) + ((Math.Pow(n, 17)) / (175472640 * Math.Pow(RL, 8))); //double y = ((Math.Pow(n, 3)) / (6 * RL)) - ((Math.Pow(n, 7)) / (336 * Math.Pow(RL, 3))) + (Math.Pow(n, 11) / (42240 * Math.Pow(RL, 5))) - (Math.Pow(n, 15) / (9676800 * Math.Pow(RL, 7))); // Flip the Y offset if start spiral is CW OR end spiral is CCW if ((isStart && dir == AeccAlignmentSpiralDirectionType.aeccAlignmentSpiralDirectionRight) || (!isStart && dir == AeccAlignmentSpiralDirectionType.aeccAlignmentSpiralDirectionLeft) ) { y *= -1; } pts.Add(Point.ByCoordinates(x, y, 0)); n += step; } // Create spiral at 0,0 NurbsCurve spiralBase = NurbsCurve.ByControlPoints(pts, 3); // Degree by default is 3 if (isStart) { pt = ptStart; angRot = 90 - (dirStart * (180 / Math.PI)); } else { pt = ptEnd; angRot = 270 - (dirEnd * (180 / Math.PI)); } // Coordinate system on outer spiral point CoordinateSystem csOrig = CoordinateSystem.ByOrigin(pt); CoordinateSystem cs = csOrig.Rotate(pt, Vector.ZAxis(), angRot); NurbsCurve spiral = (NurbsCurve)spiralBase.Transform(cs); output.Add(spiral); break; default: break; } } break; } } } output = SortCurves(output); Utils.Log("Alignment.GetCurves Completed."); return(output); }