private static CurveSegment TrimAndTransform(ref Matrix trans, Plane planeA, Plane planeB, CurveSegment curve) { double startParam = planeA.IntersectCurve(curve.Geometry).First().EvaluationB.Param; double endParam = planeB.IntersectCurve(curve.Geometry).First().EvaluationB.Param; curve = CurveSegment.Create(curve.Geometry, Interval.Create(startParam, endParam)); return(curve.CreateTransformedCopy(trans)); }
public virtual ICollection <ITrimmedCurve> GetProfile() { baseRadius = Data.BaseRadius; pitchRadius = Data.PitchRadius; addendumRadius = Data.AddendumRadius; dedendumRadius = Data.DedendumRadius; basicInvolute = CurveSegment.Create(Data.CreateInvolute()); offsetAngle = Data.OffsetAngle; involutePitchTrans = Matrix.CreateRotation(Line.Create(Point.Origin, Direction.DirZ), offsetAngle); curveA = basicInvolute.CreateTransformedCopy(involutePitchTrans); curveB = curveA.CreateTransformedCopy(mirror); if (Data.TopStartAngle < Data.TopEndAngle) { topCurve = CurveSegment.Create(Data.AddendumCircle, Interval.Create(Data.TopStartAngle, Data.TopEndAngle)); period.Add(topCurve); } else // involutes intersect at top land { ICollection <IntPoint <CurveEvaluation, CurveEvaluation> > intersections = curveA.IntersectCurve(curveB.CreateTransformedCopy(Data.ToothTrans)); Debug.Assert(intersections.Count == 1); if (intersections.Count != 1) { curveA.Print(); curveB.CreateTransformedCopy(Data.ToothTrans).Print(); } curveA = CurveSegment.Create(curveA.Geometry, Interval.Create(curveA.Bounds.Start, intersections.First().EvaluationA.Param)); curveB = curveA.CreateTransformedCopy(mirror); } ICollection <IntPoint <CurveEvaluation, CurveEvaluation> > bottomIntersections = curveA.IntersectCurve(curveB); if (bottomIntersections.Count > 0 && bottomIntersections.First().Point.Vector.Magnitude > dedendumRadius) // the involutes intersect at bottom land { curveA = CurveSegment.Create(curveA.Geometry, Interval.Create(curveA.IntersectCurve(curveB).ToArray()[0].EvaluationA.Param, curveA.Bounds.End)); period.Add(curveA); period.Add(curveA.CreateTransformedCopy(mirror)); return(period); } return(null); }
private static void CreateUntransformedThreadCurves(Face cylinderFace, double pitch, double angle, Interval bounds, double positionOffset, out double radius, out Line axis, out CurveSegment innerCurve, out CurveSegment outerCurveA, out CurveSegment outerCurveB, out Matrix trans, out double innerRadius, out double outerRadius) { Cylinder cylinder = cylinderFace.Geometry as Cylinder; Debug.Assert(cylinder != null); radius = cylinder.Radius; axis = cylinder.Axis; double threadDepth = pitch / (2 * Math.Tan(angle / 2)); innerRadius = radius + threadDepth * (positionOffset - 0.5); outerRadius = radius + threadDepth * (positionOffset + 0.5); int pointsPerTurn = 360; int pointCount = (int)(bounds.Span / pitch * pointsPerTurn); var outerPoints = new Point[pointCount]; var innerPoints = new Point[pointCount]; double s = bounds.Span; double a = Const.Tau * s / pitch; for (int i = 0; i < pointCount; i++) { double t = (double)i / (pointCount - 1); double rotation = a * t; double depth = s * t; outerPoints[i] = Point.Create(outerRadius * Math.Cos(rotation), outerRadius * Math.Sin(rotation), depth); innerPoints[i] = Point.Create(innerRadius * Math.Cos(rotation), innerRadius * Math.Sin(rotation), depth); } Func <double, double, Vector> Derivative = (t, r) => Vector.Create(-r * a * Math.Sin(a * t), r * a * Math.Cos(a * t), s); var outerCurve = CurveSegment.Create(NurbsCurve.CreateThroughPoints(false, outerPoints, Accuracy.LinearResolution * 1E1, Derivative(0, outerRadius), Derivative(1, outerRadius))); innerCurve = CurveSegment.Create(NurbsCurve.CreateThroughPoints(false, innerPoints, Accuracy.LinearResolution * 1E1, Derivative(0, innerRadius), Derivative(1, innerRadius))); var translation = Matrix.CreateTranslation(Vector.Create(0, 0, -pitch)); var offset = Matrix.CreateTranslation(Direction.DirZ * pitch / 2); outerCurveA = outerCurve.CreateTransformedCopy(translation * offset); outerCurveB = outerCurve.CreateTransformedCopy(translation * offset.Inverse); innerCurve = innerCurve.CreateTransformedCopy(translation); trans = Matrix.CreateMapping(Frame.Create(axis.Evaluate(bounds.Start).Point, axis.Direction)); }
public override ICollection <ITrimmedCurve> GetProfile() { IPart iPart = Window.ActiveWindow.Scene as Part; if (base.GetProfile() != null) { return(period); } CurveSegment trochoidA = CurveSegment.Create(Data.CreateConjugateTrochoid(ConjugateGearData)); Line tangentLine = Line.CreateTangentToOne(Plane.PlaneXY, new CurveParam(trochoidA.Geometry, (trochoidA.Bounds.Start + trochoidA.Bounds.End) * 3 / 4), Point.Origin); ICollection <IntPoint <CurveEvaluation, CurveEvaluation> > intersectionsInvoluteTangent = tangentLine.IntersectCurve(trochoidA.Geometry); double paramA, paramB; if (intersectionsInvoluteTangent.Count != 1) // Apparently, an ACIS bug can cause the intersection to miss even though the tangent line is perfect, so we work around it. { Separation sep = tangentLine.GetClosestSeparation(trochoidA.Geometry); paramA = tangentLine.ProjectPoint(sep.PointA).Param; paramB = trochoidA.Geometry.ProjectPoint(sep.PointB).Param; } else { IntPoint <CurveEvaluation, CurveEvaluation> intersectionInvoluteTangent = intersectionsInvoluteTangent.ToArray()[0]; paramA = intersectionInvoluteTangent.EvaluationA.Param; paramB = intersectionInvoluteTangent.EvaluationB.Param; } CurveSegment tangentLineSegment = CurveSegment.Create(tangentLine, Interval.Create( Data.DedendumRadius, // line origin is world origin in direction of tangency paramA )); double tangentAngle = Math.Atan(tangentLine.Direction.Y / tangentLine.Direction.X); CurveSegment baseCircleSegment = CurveSegment.Create(Data.DedendumCircle, Interval.Create(2 * Math.PI - tangentAngle, tangentAngle)); ICollection <IntPoint <CurveEvaluation, CurveEvaluation> > intersectionsInvoluteTrochoid = trochoidA.IntersectCurve(curveA); if (intersectionsInvoluteTrochoid.Count == 0) // error { DesignCurve.Create(iPart, baseCircleSegment); DesignCurve.Create(iPart, tangentLineSegment); DesignCurve.Create(iPart, trochoidA); DesignCurve.Create(iPart, trochoidA.CreateTransformedCopy(mirror)); DesignCurve.Create(iPart, curveA); DesignCurve.Create(iPart, curveA.CreateTransformedCopy(mirror)); return(null); } IntPoint <CurveEvaluation, CurveEvaluation> intersectionInvoluteTrochoid = intersectionsInvoluteTrochoid.ToArray()[0]; // if (tangentLineSegment.IntersectCurve(curveA).Count > 0) an ACIS intersection bug prevents this from working. e.g. 13 tooth gear with 20 degree pressure angle if (paramB > intersectionInvoluteTrochoid.EvaluationA.Param) { return(new ExtendedToothProfile(Data).GetProfile()); } trochoidA = CurveSegment.Create(trochoidA.Geometry, Interval.Create(paramB, intersectionInvoluteTrochoid.EvaluationA.Param)); period.Add(trochoidA); period.Add(trochoidA.CreateTransformedCopy(mirror)); curveA = CurveSegment.Create(curveA.Geometry, Interval.Create(intersectionInvoluteTrochoid.EvaluationB.Param, curveA.Bounds.End)); period.Add(curveA); period.Add(curveA.CreateTransformedCopy(mirror)); period.Add(tangentLineSegment); period.Add(tangentLineSegment.CreateTransformedCopy(mirror)); period.Add(baseCircleSegment); return(period); }
public override ICollection <ITrimmedCurve> GetProfile() { IPart iPart = Window.ActiveWindow.Scene as Part; if (base.GetProfile() != null) { return(period); } CurveSegment trochoidA = CurveSegment.Create(Data.CreateConjugateTrochoid(ConjugateGearData)); ICollection <IntPoint <CurveEvaluation, CurveEvaluation> > intersectionsInvolute = trochoidA.IntersectCurve(curveA); CurveSegment addendumCircle = null; Matrix conjugateTrans = Matrix.CreateTranslation(Vector.Create(Data.PitchRadius + ConjugateGearData.PitchRadius, 0, 0)); // involute traced by only one corner // addendumCircle = CurveSegment.Create(ConjugateGearData.AddendumCircle).CreateTransformedCopy(conjugateTrans); // ClosestSeparation extension technique, with scaling Circle largeCircle = Circle.Create(Frame.Create(conjugateTrans * Point.Origin, Direction.DirX, Direction.DirY), ConjugateGearData.PitchRadius + pitchRadius); Separation separation = CurveSegment.Create(largeCircle).GetClosestSeparation(trochoidA); Circle circle = Circle.Create(largeCircle.Frame, (separation.PointB - largeCircle.Frame.Origin).Magnitude - Accuracy.LinearResolution * 100); addendumCircle = CurveSegment.Create(circle); //// Three point circle techique //Matrix rotation = Matrix.CreateRotation(Line.Create(conjugateTrans * Point.Origin, Direction.DirZ), 2 * Math.PI / 3); //double param = trochoidA.Geometry.Parameterization.Range.Value.GetParameter(0.5); //CurveSegment curve0 = trochoidA.CreateTransformedCopy(Matrix.Identity); //CurveSegment curve1 = curve0.CreateTransformedCopy(rotation); //CurveSegment curve2 = curve1.CreateTransformedCopy(rotation); //Circle circle = Circle.CreateTangentToThree( // Plane.PlaneXY, // new CurveParam(curve0.Geometry, param), // new CurveParam(curve1.Geometry, param), // new CurveParam(curve2.Geometry, param) //); // addendumCircle = CurveSegment.Create(Circle.Create(Frame.Create(circle.Frame.Origin, Direction.DirX, Direction.DirY), circle.Radius - Accuracy.LinearResolution * 10)); if (intersectionsInvolute.Count == 0) // error { DesignCurve.Create(iPart, CurveSegment.Create(addendumCircle.Geometry)); DesignCurve.Create(iPart, trochoidA); DesignCurve.Create(iPart, trochoidA.CreateTransformedCopy(mirror)); DesignCurve.Create(iPart, curveA); DesignCurve.Create(iPart, curveA.CreateTransformedCopy(mirror)); return(null); } /// else { IntPoint <CurveEvaluation, CurveEvaluation> intersectionInvolute = intersectionsInvolute.ToArray()[0]; addendumCircle = addendumCircle.CreateTransformedCopy(Matrix.CreateScale(1 / 1.00, (addendumCircle.Geometry as Circle).Frame.Origin)); double maxDist = 0; ICollection <IntPoint <CurveEvaluation, CurveEvaluation> > intersections = trochoidA.IntersectCurve(addendumCircle); IntPoint <CurveEvaluation, CurveEvaluation> intersectionOther = intersections.First(); foreach (IntPoint <CurveEvaluation, CurveEvaluation> intersection in intersections) { double dist = Math.Abs(intersection.EvaluationA.Param - intersectionInvolute.EvaluationA.Param); if (dist > maxDist) { intersectionOther = intersection; maxDist = dist; } } // period.Add(addendumCircle); if (maxDist == 0) //error { DesignCurve.Create(iPart, CurveSegment.Create(addendumCircle.Geometry)); DesignCurve.Create(iPart, trochoidA); DesignCurve.Create(iPart, trochoidA.CreateTransformedCopy(mirror)); DesignCurve.Create(iPart, curveA); DesignCurve.Create(iPart, curveA.CreateTransformedCopy(mirror)); return(null); } period.Add(CurveSegment.Create(addendumCircle.Geometry, Interval.Create(intersectionOther.EvaluationB.Param, 2 * Math.PI - intersectionOther.EvaluationB.Param))); // } //CurveSegment trochoidB = trochoidA.CreateTransformedCopy(mirror); //intersectionOther = trochoidA.IntersectCurve(trochoidB).ToArray()[0]; trochoidA = CurveSegment.Create(trochoidA.Geometry, Interval.Create(intersectionOther.EvaluationA.Param, intersectionInvolute.EvaluationA.Param)); period.Add(trochoidA); period.Add(trochoidA.CreateTransformedCopy(mirror)); curveA = CurveSegment.Create(curveA.Geometry, Interval.Create(intersectionInvolute.EvaluationB.Param, curveA.Bounds.End)); period.Add(curveA); period.Add(curveA.CreateTransformedCopy(mirror)); return(period); }
public virtual ICollection<ITrimmedCurve> GetProfile() { baseRadius = Data.BaseRadius; pitchRadius = Data.PitchRadius; addendumRadius = Data.AddendumRadius; dedendumRadius = Data.DedendumRadius; basicInvolute = CurveSegment.Create(Data.CreateInvolute()); offsetAngle = Data.OffsetAngle; involutePitchTrans = Matrix.CreateRotation(Line.Create(Point.Origin, Direction.DirZ), offsetAngle); curveA = basicInvolute.CreateTransformedCopy(involutePitchTrans); curveB = curveA.CreateTransformedCopy(mirror); if (Data.TopStartAngle < Data.TopEndAngle) { topCurve = CurveSegment.Create(Data.AddendumCircle, Interval.Create(Data.TopStartAngle, Data.TopEndAngle)); period.Add(topCurve); } else { // involutes intersect at top land ICollection<IntPoint<CurveEvaluation, CurveEvaluation>> intersections = curveA.IntersectCurve(curveB.CreateTransformedCopy(Data.ToothTrans)); Debug.Assert(intersections.Count == 1); if (intersections.Count != 1) { curveA.Print(); curveB.CreateTransformedCopy(Data.ToothTrans).Print(); } curveA = CurveSegment.Create(curveA.Geometry, Interval.Create(curveA.Bounds.Start, intersections.First().EvaluationA.Param)); curveB = curveA.CreateTransformedCopy(mirror); } ICollection<IntPoint<CurveEvaluation, CurveEvaluation>> bottomIntersections = curveA.IntersectCurve(curveB); if (bottomIntersections.Count > 0 && bottomIntersections.First().Point.Vector.Magnitude > dedendumRadius) { // the involutes intersect at bottom land curveA = CurveSegment.Create(curveA.Geometry, Interval.Create(curveA.IntersectCurve(curveB).ToArray()[0].EvaluationA.Param, curveA.Bounds.End)); period.Add(curveA); period.Add(curveA.CreateTransformedCopy(mirror)); return period; } return null; }
private static CurveSegment TrimAndTransform(ref Matrix trans, Plane planeA, Plane planeB, CurveSegment curve) { double startParam = planeA.IntersectCurve(curve.Geometry).First().EvaluationB.Param; double endParam = planeB.IntersectCurve(curve.Geometry).First().EvaluationB.Param; curve = CurveSegment.Create(curve.Geometry, Interval.Create(startParam, endParam)); return curve.CreateTransformedCopy(trans); }
private static void CreateUntransformedThreadCurves(Face cylinderFace, double pitch, double angle, Interval bounds, double positionOffset, out double radius, out Line axis, out CurveSegment innerCurve, out CurveSegment outerCurveA, out CurveSegment outerCurveB, out Matrix trans, out double innerRadius, out double outerRadius) { Cylinder cylinder = cylinderFace.Geometry as Cylinder; Debug.Assert(cylinder != null); radius = cylinder.Radius; axis = cylinder.Axis; double threadDepth = pitch / (2 * Math.Tan(angle / 2)); innerRadius = radius + threadDepth * (positionOffset - 0.5); outerRadius = radius + threadDepth * (positionOffset + 0.5); int pointsPerTurn = 360; int pointCount = (int)(bounds.Span / pitch * pointsPerTurn); var outerPoints = new Point[pointCount]; var innerPoints = new Point[pointCount]; double s = bounds.Span; double a = Const.Tau * s / pitch; for (int i = 0; i < pointCount; i++) { double t = (double)i / (pointCount - 1); double rotation = a * t; double depth = s * t; outerPoints[i] = Point.Create(outerRadius * Math.Cos(rotation), outerRadius * Math.Sin(rotation), depth); innerPoints[i] = Point.Create(innerRadius * Math.Cos(rotation), innerRadius * Math.Sin(rotation), depth); } Func<double, double, Vector> Derivative = (t, r) => Vector.Create(-r * a * Math.Sin(a * t), r * a * Math.Cos(a * t), s); var outerCurve = CurveSegment.Create(NurbsCurve.CreateThroughPoints(false, outerPoints, Accuracy.LinearResolution * 1E1, Derivative(0, outerRadius), Derivative(1, outerRadius))); innerCurve = CurveSegment.Create(NurbsCurve.CreateThroughPoints(false, innerPoints, Accuracy.LinearResolution * 1E1, Derivative(0, innerRadius), Derivative(1, innerRadius))); var translation = Matrix.CreateTranslation(Vector.Create(0, 0, -pitch)); var offset = Matrix.CreateTranslation(Direction.DirZ * pitch / 2); outerCurveA = outerCurve.CreateTransformedCopy(translation * offset); outerCurveB = outerCurve.CreateTransformedCopy(translation * offset.Inverse); innerCurve = innerCurve.CreateTransformedCopy(translation); trans = Matrix.CreateMapping(Frame.Create(axis.Evaluate(bounds.Start).Point, axis.Direction)); }