public static CurveSegment CreateHelixAroundCurve(this ITrimmedCurve curveSegment, double turns, double radius, double pointCount) { var points = new List <Point>(); Direction lastNormal = curveSegment.Geometry.Evaluate(curveSegment.Bounds.Start).Tangent.ArbitraryPerpendicular; for (int i = 0; i < pointCount; i++) { double ratio = (double)i / pointCount; double param = curveSegment.Bounds.Start + ratio * curveSegment.Bounds.Span; CurveEvaluation curveEval = curveSegment.Geometry.Evaluate(param); Direction normal = Direction.Cross(Direction.Cross(curveEval.Tangent, lastNormal), curveEval.Tangent); if (normal.IsZero) { normal = lastNormal; } Point point = curveEval.Point; Matrix rotation = Matrix.CreateRotation(Line.Create(point, curveEval.Tangent), 2 * Math.PI * turns * ratio); point += radius * normal; point = rotation * point; points.Add(point); lastNormal = normal; } return(CurveSegment.Create(NurbsCurve.CreateThroughPoints(false, points, 0.000001))); }
public static Body CreateCable(ITrimmedCurve iTrimmedCurve, double diameter) { double radius = diameter / 2; CurveEvaluation curveEvaluation = iTrimmedCurve.Geometry.Evaluate(iTrimmedCurve.Bounds.Start); Point startPoint = curveEvaluation.Point; Direction dirZ = curveEvaluation.Tangent; Direction dirX = dirZ.ArbitraryPerpendicular; Direction dirY = Direction.Cross(dirZ, dirX); Frame profileFrame = Frame.Create(startPoint, dirX, dirY); Circle profileCircle = Circle.Create(profileFrame, radius); IList <ITrimmedCurve> profile = new List <ITrimmedCurve>(); profile.Add(CurveSegment.Create(profileCircle)); IList <ITrimmedCurve> path = new List <ITrimmedCurve>(); path.Add(iTrimmedCurve); Body body = Body.SweepProfile(Plane.Create(profileFrame), profile, path); if (body == null) { Debug.Fail("Sweep failed."); return(null); } return(body); }
protected override void OnExecute(Command command, ExecutionContext context, System.Drawing.Rectangle buttonRect) { if (excelWorksheet == null) { excelWorksheet = new ExcelWorksheet(); } Window activeWindow = Window.ActiveWindow; List <ITrimmedCurve> iTrimmedCurves = new List <ITrimmedCurve>(activeWindow.GetAllSelectedITrimmedCurves()); if (iTrimmedCurves.Count != 2) { return; } ITrimmedCurve curveA = iTrimmedCurves[0]; ITrimmedCurve curveB = iTrimmedCurves[1]; var intersections = new List <IntPoint <CurveEvaluation, CurveEvaluation> >(curveA.IntersectCurve(curveB)); CurveEvaluation evalA = curveA.ProjectPoint(intersections[0].Point); CurveEvaluation evalB = curveB.ProjectPoint(intersections[0].Point); double angle = Math.Acos(Vector.Dot(evalA.Tangent.UnitVector, evalB.Tangent.UnitVector)); excelWorksheet.SetCell(row++, 1, angle * 180 / Math.PI); }
private static void MakeNurbsEndTangent(Line cleaveLine, ControlPoint[] controlPoints, int endIndex, int tangentIndex) { Point initialPoint = controlPoints[endIndex].Position; CurveEvaluation curveEvaluation = cleaveLine.ProjectPoint(initialPoint); if (initialPoint == curveEvaluation.Point) { return; } controlPoints[endIndex] = new ControlPoint(curveEvaluation.Point, controlPoints[endIndex].Weight); Line tangentLine = Line.Create(curveEvaluation.Point, (initialPoint - curveEvaluation.Point).Direction); curveEvaluation = tangentLine.ProjectPoint(controlPoints[tangentIndex].Position); controlPoints[tangentIndex] = new ControlPoint(curveEvaluation.Point, controlPoints[tangentIndex].Weight); }
/// <summary> /// Attempt to find convexity-sensitive angle between the normals of the adjacent faces of an edge using its midpoint. Returns a negavive angle for concave edges, 0 for tangent, or postitive for convex. /// </summary> /// <param name="edge">The Edge who's convexity is to be determined.</param> /// <returns></returns> public static double GetAngle(this Edge edge) { if (edge.Fins.Count != 2) { throw new ArgumentException("Edge must have two fins in order to have angle."); } CurveEvaluation curveEval = edge.Geometry.Evaluate((edge.Bounds.Start + edge.Bounds.End) / 2); Point edgePoint = curveEval.Point; Direction tangent = curveEval.Tangent; Fin finA = edge.Fins.ToArray()[0]; if (finA.IsReversed ^ finA.Edge.IsReversed) { tangent = -tangent; } Direction dirA = finA.Loop.Face.ProjectPoint(edgePoint).Normal; if (finA.Loop.Face.IsReversed) { dirA = -dirA; } Fin finB = edge.Fins.ToArray()[1]; Direction dirB = finB.Loop.Face.ProjectPoint(edgePoint).Normal; if (finB.Loop.Face.IsReversed) { dirB = -dirB; } double sense = Math.Asin(Math.Min(Math.Max(Vector.Dot(Direction.Cross(tangent, dirA).UnitVector, dirB.UnitVector), -1), 1)); // can be slightly out of range of [-1 ,1] if (Accuracy.AngleIsZero(sense)) { return(0); } return(Math.Abs(AddInHelper.AngleBetween(dirA, dirB)) * (sense > 0 ? 1 : -1)); }
public bool TryGetPointAlongCurve(double param, out Point point) { point = Point.Origin; double travelled = 0; int i; for (i = 0; i < orientedCurves.Count; i++) { double length = orientedCurves[i].Length; if (param - travelled < length) { break; } travelled += length; } double offsetParam; if (i == orientedCurves.Count) // handles the endpoint case { CurveEvaluation curveEval = orientedCurves[i - 1].TrimmedCurve.Geometry.Evaluate(orientedCurves[i - 1].Bounds.End); point = curveEval.Point; return(true); } if (orientedCurves[i].TryOffsetAlongCurve(orientedCurves[i].Bounds.Start, param - travelled, out offsetParam)) { CurveEvaluation curveEval = orientedCurves[i].TrimmedCurve.Geometry.Evaluate(offsetParam); point = curveEval.Point; return(true); } return(false); }
protected override void OnExecute(Command command, ExecutionContext context, System.Drawing.Rectangle buttonRect) { base.OnExecute(command, context, buttonRect); List <ITrimmedCurve> trimmedCurves = new List <ITrimmedCurve>(); foreach (ITrimmedCurve trimmedCurve in activeWindow.GetAllSelectedITrimmedCurves()) { trimmedCurves.Add(trimmedCurve); } TrimmedCurveChain curveChain = new TrimmedCurveChain(trimmedCurves); double length = curveChain.Length; int count = (int)Math.Floor(length / dashMinSize / 2) * 2; if (curveChain.StartPoint != curveChain.EndPoint) // odd number when not closed curve { count++; } List <DesignCurve> dashes = new List <DesignCurve>(); double lastParam = curveChain.Bounds.Start; Point lastPoint; Debug.Assert(curveChain.TryGetPointAlongCurve(lastParam, out lastPoint)); for (int i = 0; i < count; i++) { Point point; if (curveChain.TryGetPointAlongCurve(lastParam -= length / count, out point)) { if (i % 2 == 1) { DesignCurve dash = DesignCurve.Create(part, CurveSegment.Create(lastPoint, point)); dash.Layer = dashLayer; dashes.Add(dash); } #if false // tori ShapeHelper.CreateTorus( new Point[] { point, lastPoint }.Average(), (point - lastPoint).Direction, 0.188 * inches, 0.75 * inches, part ); #endif lastPoint = point; } } #if false // cylinders for (int i = 1; i < count; i++) { CurveEvaluation eval = dashes[i].Shape.Geometry.Evaluate(dashes[i].Shape.Bounds.Start); Direction dir1 = eval.Tangent; eval = dashes[i - 1].Shape.Geometry.Evaluate(dashes[i - 1].Shape.Bounds.End); Direction dir2 = eval.Tangent; if (dir1 == dir2) { DatumPlane.Create(part, "miter parallel", Plane.Create(Frame.Create(eval.Point, eval.Tangent.ArbitraryPerpendicular, Direction.Cross(eval.Tangent.ArbitraryPerpendicular, eval.Tangent)))); continue; } Direction averageDir = (dir1.UnitVector + dir2.UnitVector).Direction; Direction xDir = Direction.Cross(averageDir, dir1); // DatumPlane.Create(part, "miter", Plane.Create(Frame.Create(eval.Point, xDir, Direction.Cross(xDir, averageDir)))); double offset = 0.0001 / 2; ShapeHelper.CreateCylinder(eval.Point + averageDir * offset, eval.Point - averageDir * offset, 7 * inches, part); } #endif }
public static ICollection <Primitive> CreateCylinderMesh(Point point1, Point point2, double diameter, int sides) { Vector heightVector = point2 - point1; Circle circle1 = Circle.Create(Frame.Create(point1, heightVector.Direction), diameter / 2); Circle circle2 = Circle.Create(Frame.Create(point2, heightVector.Direction), diameter / 2); var cylinderVertices = new List <FacetVertex>(); var end1Vertices = new List <FacetVertex>(); var end2Vertices = new List <FacetVertex>(); var tempVertices = new List <Point>(); //TBD remove when we can do seletction on meshes double angle = 2 * Math.PI / (double)sides; for (int i = 0; i < sides; i++) { CurveEvaluation eval1 = circle1.Evaluate((double)i * angle); CurveEvaluation eval2 = circle2.Evaluate(((double)i + 0.5) * angle); cylinderVertices.Add(new FacetVertex(eval1.Point, (eval1.Point - circle1.Frame.Origin).Direction)); cylinderVertices.Add(new FacetVertex(eval2.Point, (eval2.Point - circle2.Frame.Origin).Direction)); end1Vertices.Add(new FacetVertex(eval1.Point, heightVector.Direction)); end2Vertices.Add(new FacetVertex(eval2.Point, -heightVector.Direction)); tempVertices.Add(eval1.Point); tempVertices.Add(eval2.Point); } var cylinderFacets = new List <Facet>(); for (int i = 0; i < sides; i++) { int f00 = 2 * i; int f01 = f00 + 1; int f10 = f00 + 2 >= sides * 2 ? 0 : f00 + 2; int f11 = f10 + 1; cylinderFacets.Add(new Facet(f00, f10, f01)); cylinderFacets.Add(new Facet(f10, f11, f01)); } var end1Facets = new List <Facet>(); var end2Facets = new List <Facet>(); for (int i = 1; i < sides - 1; i++) { end1Facets.Add(new Facet(0, i + 1, i)); end2Facets.Add(new Facet(0, i, i + 1)); } var primitives = new List <Primitive>(); primitives.Add(MeshPrimitive.Create(cylinderVertices, cylinderFacets)); primitives.Add(MeshPrimitive.Create(end1Vertices, end1Facets)); primitives.Add(MeshPrimitive.Create(end2Vertices, end2Facets)); primitives.Add(PolylinePrimitive.Create(tempVertices)); //TBD remove return(primitives); }