double[] ComputeAngles(Circle[] circles) { int count = circles.Length; var angles = new double[count]; for (int i = 0; i < count; i++) { int otherIndex = i == count - 1 ? 0 : i + 1; angles[i] = AddInHelper.AngleBetween(circles[i].Axis.Direction, circles[otherIndex].Axis.Direction) / 2; } angles[count - 1] = Math.PI / 2 - angles[count - 1]; return(angles); }
public void Render() { renderedBody = CreateUnfoldedFaceBody(); DesignBody designBody = DesignBody.Create(flatBody.FlatPart, Resources.FlatFaceName, renderedBody); designBody.Layer = NoteHelper.CreateOrGetLayer(Window.ActiveWindow.Document, Resources.FlatFaceLayerName, System.Drawing.Color.Beige); foreach (FlatLoop flatLoop in Loops) { foreach (FlatFin flatFin in flatLoop.Fins.Where(f => !f.IsInternal)) { DesignCurve designCurve = DesignCurve.Create(flatBody.FlatPart, flatFin.SourceFin.Edge); designCurve.Transform(transform); designCurve.Layer = NoteHelper.CreateOrGetLayer(Window.ActiveWindow.Document, Resources.FlatCuttingLinesLayerName, System.Drawing.Color.Blue); } foreach (FlatFin flatFin in flatLoop.Fins.Where(f => f.AdjacentFin != null)) { if ( flatBody.FlatPattern.IsCreatingDashes && Accuracy.CompareAngles(AddInHelper.AngleBetween(flatFin.FlatFace.SourceFace.Geometry.Evaluate(PointUV.Origin).Normal, flatFin.AdjacentFin.FlatFace.SourceFace.Geometry.Evaluate(PointUV.Origin).Normal), flatBody.FlatPattern.BreakAngle) <= 0) { Layer breakLayer = NoteHelper.CreateOrGetLayer(Window.ActiveWindow.Document, Resources.BreakLinesLayerName, System.Drawing.Color.DarkBlue); if (flatBody.FlatPattern.DashSize == 0) { DesignCurve desCurve = DesignCurve.Create(FlatBody.FlatPart, flatFin.AsCurveSegment()); desCurve.Layer = breakLayer; } else { DashesButtonCapsule.CreateDashes(flatFin.AsCurveSegment(), FlatBody.FlatPart, flatBody.FlatPattern.DashSize, breakLayer); } } } } }
public void Iterate() { Iteration++; var newVParameters = new CircularList <CircularList <double> >(iSteps * 2); var backupVParameters = new CircularList <CircularList <double> >(iSteps * 2); var newTabAngles = new CircularList <CircularList <double> >(iSteps * 2); for (int i = 0; i < iSteps * 2; i++) { newVParameters.Add(new CircularList <double>(jSteps)); backupVParameters.Add(new CircularList <double>(jSteps)); newTabAngles.Add(new CircularList <double>(jSteps)); for (int j = 0; j < jSteps; j++) { newVParameters[i].Add(vParameters[i][j]); backupVParameters[i].Add(vParameters[i][j]); newTabAngles[i].Add(tabAngles[i][j]); } } double cumulativeErrorTally = 0; MaxError = 0; for (int i = 0; i < iSteps * 2; i++) { for (int j = 0; j < jSteps; j++) { bool swap = j % 2 == 0; int iOtherDir = swap ? -1 : 1; int iOther = i + iOtherDir; Circle baseCircle = GetTabFromPoints(true, i, j, iOther); Circle circle0 = GetTabFromPoints(true, iOther, j - 1, i); Circle circle1 = GetTabFromPoints(true, iOther, j + 1, i); double distance0 = (baseCircle.Frame.Origin - circle0.Frame.Origin).Magnitude - baseCircle.Radius - circle0.Radius; double distance1 = (baseCircle.Frame.Origin - circle1.Frame.Origin).Magnitude - baseCircle.Radius - circle1.Radius; cumulativeErrorTally += distance0 * distance0 + distance1 * distance1; MaxError = Math.Max(Math.Abs(distance0), MaxError); MaxError = Math.Max(Math.Abs(distance1), MaxError); double angleAdjust = (distance0 + distance1) / 2 * AngleForce / GetSpanAt(i, j) / baseCircle.Radius; // / GetSpanAt(i, j) / baseCircle.Radius; // / baseCircle.Radius; newTabAngles[i][j] -= angleAdjust; newTabAngles[i][j - 1] -= angleAdjust / 2; newTabAngles[i][j + 1] -= angleAdjust / 2; double iAngle = AddInHelper.AngleBetween( circle0.Frame.Origin - baseCircle.Frame.Origin, circle1.Frame.Origin - baseCircle.Frame.Origin ); double vOffset = (distance1 - distance0) * VForce; //double uAngleOffset = -(Math.PI / 2 - Math.Abs(iAngle)) * UAngleForce; double uAngleOffset = -(Math.PI * 2 / 3 - Math.Abs(iAngle)) * UAngleForce; Circle circleV = GetTabFromPoints(true, iOther, j, i); double distanceV = (baseCircle.Frame.Origin - circleV.Frame.Origin).Magnitude - baseCircle.Radius - circleV.Radius; double uTouchOffset = -distanceV * UTouchForce; double averageOffset = 0; double averageAngle = 0; double count = 0; #if false for (int ii = i - 1; ii <= i + 1; ii++) { for (int jj = j - 2; jj <= j + 2; jj++) { if (i == ii && j == jj) { continue; } double weight = (double)1 / (Math.Pow(i - ii, 2) + Math.Pow(j - jj, 2)); averageOffset += GetSpanAt(ii, jj) * weight; averageAngle += GetTabFromPoints(true, i, j, j % 2 == 0 ? i - 1 : i + 1).Radius *weight; count += weight; } } averageOffset = averageOffset / count - GetSpanAt(i, j); averageOffset *= -AverageVForce / 2; averageAngle = averageAngle / count - baseCircle.Radius; newTabAngles[i][j] += averageAngle * AverageTabAngleForce; #elif true foreach (int ii in new int[] { i, iOther }) { foreach (int jj in new int[] { j - 1, j + 1 }) { averageAngle += GetTabFromPoints(true, ii, jj, ii == i ? iOther : i).Radius; count++; } } averageOffset += GetSpanAt(i - 1, j); averageOffset += GetSpanAt(i + 1, j); averageOffset += GetSpanAt(i, j - 1); averageOffset += GetSpanAt(i, j + 1); averageOffset /= 4; averageOffset = averageOffset / count - GetSpanAt(i, j); averageOffset *= -AverageVForce / 2; averageAngle = averageAngle / count - baseCircle.Radius; newTabAngles[i][j] -= averageAngle * AverageTabAngleForce; #else Point midpointV = GetFivePointNurbsAverage(new int[, ] { { i, j - 2 }, { i, j - 1 }, { i, j }, { i, j + 1 }, { i, j + 2 } }); Point midpointD0 = GetFivePointNurbsAverage(new int[, ] { { i - iOtherDir, j - 2 }, { i, j - 1 }, { i, j }, { i + iOtherDir, j + 1 }, { i + 2 * iOtherDir, j + 2 } }); Point midpointD1 = GetFivePointNurbsAverage(new int[, ] { { i - iOtherDir, j + 2 }, { i, j + 1 }, { i, j }, { i + iOtherDir, j - 1 }, { i + 2 * iOtherDir, j - 2 } }); Point midpointU = GetFivePointNurbsAverage(new int[, ] { { i - 2 * iOtherDir, j }, { i - iOtherDir, j }, { i, j }, { i + iOtherDir, j }, { i + 2 * iOtherDir, j } }); averageOffset = (midpointV.Y + midpointU.Y) / 2 - GetSpanAt(i, j); averageOffset *= -AverageVForce / 2; averageAngle = (midpointV.X + 2 * midpointD0.X + 2 * midpointD1.X) / 5 - tabAngles[i][j]; newTabAngles[i][j] += averageAngle * AverageTabAngleForce; #endif double size = 1; // (points[i][j + 1] - points[i][j]).Magnitude; double slip = (uAngleOffset + averageOffset + uTouchOffset) * size; newVParameters[i][j] += vOffset + slip; newVParameters[i][j + 1] += vOffset - slip; newVParameters[i][j - 1] += (vOffset + slip) / 2; newVParameters[i][j + 2] += (vOffset - slip) / 2; // double oldSpan = (points[i][j + 1] - points[i][j]).Magnitude; // double newSpan = (points[i][j + 1] - points[i][j]).Magnitude; Trace.WriteIf(Iteration % 400 == 0, tabAngles[i][j] + " "); // Trace.WriteIf(Iteration % 400 == 0, iAngle + " "); // Trace.WriteIf(Iteration % 400 == 0, GetSpanAt(i,j) + " "); } Trace.WriteLineIf(Iteration % 400 == 0, ""); } for (int i = 0; i < iSteps * 2; i++) { for (int j = 0; j < jSteps; j++) { newTabAngles[i][j] = Math.Max(Math.PI / 2, newTabAngles[i][j]); newTabAngles[i][j] = Math.Min(Math.PI * 3 / 4, newTabAngles[i][j]); double l1 = backupVParameters[i][j + 1] - backupVParameters[i][j]; double l2 = newVParameters[i][j + 1] - newVParameters[i][j]; double b1 = Math.PI - tabAngles[i][j]; double a = l1 / l2 / Math.Tan(b1 / 2) * (1 + 1 / Math.Cos(b1 / 2)); double phi = 2 * Math.Atan(1 / a); tabAngles[i][j] = Math.PI - 2 * phi; //double b2 = 2 * Math.Asin(l2 / l1 * Math.Sin(b1 / 2)); //tabAngles[i][j] = Math.PI - b2; } } for (int i = 0; i < iSteps * 2; i++) { // make intersecting tabs identical //double angle = ( // newTabAngles[i][0] + // newTabAngles[i + iSteps][0] + // newTabAngles[i + iSteps / 2][jSteps / 2] + // newTabAngles[i + 3 * iSteps / 2][jSteps / 2] //) / 4; //newTabAngles[i][0] = angle; //newTabAngles[i + iSteps][0] = angle; //newTabAngles[i + iSteps / 2][jSteps / 2] = angle; //newTabAngles[i + 3 * iSteps / 2][jSteps / 2] = angle; double span = ( (newVParameters[i][1] - newVParameters[i][0]) + (newVParameters[i + iSteps][1] - newVParameters[i + iSteps][0]) + (newVParameters[i + iSteps / 2][jSteps / 2 + 1] - newVParameters[i + iSteps / 2][jSteps / 2]) + (newVParameters[i + 3 * iSteps / 2][jSteps / 2 + 1] - newVParameters[i + 3 * iSteps / 2][jSteps / 2]) ) / 8; newVParameters[i][0] = -span; newVParameters[i][1] = span; newVParameters[i + iSteps][0] = -span; newVParameters[i + iSteps][1] = span; newVParameters[i + iSteps / 2][jSteps / 2] = Math.PI - span; newVParameters[i + iSteps / 2][jSteps / 2 + 1] = Math.PI + span; newVParameters[i + 3 * iSteps / 2][jSteps / 2] = Math.PI - span; newVParameters[i + 3 * iSteps / 2][jSteps / 2 + 1] = Math.PI + span; } // Average antipodal points // for l(i, j), // l(i, j) == l(-i, pi+j)* == l(i+2pi, -j) == l(-i-2pi, pi-j)* // Where * means x=x, y=-y, z=-z for (int i = 0; i < iSteps * 2; i++) { for (int j = 0; j < jSteps / 2; j++) { double average = ( newVParameters[i][j] + newVParameters[-i][j + jSteps / 2] - Math.PI + (j < 2 ? 0 : 2 * Math.PI) - newVParameters[i + iSteps][-j + 1] + Math.PI - newVParameters[-i - iSteps][-j + jSteps / 2 + 1] ) / 4; newVParameters[i][j] = average; newVParameters[-i][j + jSteps / 2] = average + Math.PI; newVParameters[i + iSteps][-j + 1] = (j < 2 ? 0 : 2 * Math.PI) - average; newVParameters[-i - iSteps][-j + jSteps / 2 + 1] = Math.PI - average; average = ( tabAngles[i][j] + tabAngles[-i][j + jSteps / 2 + 1] + tabAngles[i + iSteps][-j] + tabAngles[-i - iSteps][-j + jSteps / 2 + 1] ) / 4; tabAngles[i][j] = average; tabAngles[-i][j + jSteps / 2 + 1] = average; tabAngles[i + iSteps][-j] = average; tabAngles[-i - iSteps][-j + jSteps / 2 + 1] = average; } } CumulativeError = Math.Sqrt(cumulativeErrorTally / (iSteps * 2 * jSteps * 2)); // Trace.WriteLine(lastCumulativeError); // We're not calculating the points for the last iteration. Whatevs. vParameters = newVParameters; tabAngles = newTabAngles; for (int i = 0; i < iSteps * 2; i++) { double u = 2 * Math.PI * (double)i / iSteps; for (int j = 0; j < jSteps; j++) { points[i][j] = Lawson.Evaluate(PointUV.Create(vParameters[i][j], u), p, q, circleAngle, inverseOffset, true) * scale; // Trace.WriteLine(string.Format("{0} {1} {2}", i, j, tabAngles[i][j])); } } }
public void Iterate() { Iteration++; //var newVParameters = new List<List<double>>(steps + 1); //var backupVParameters = new List<List<double>>(steps + 1); //var newTabAngles = new List<List<double>>(steps + 1); for (int i = 0; i < steps; i++) { //newVParameters.Add(new List<double>(steps + 1)); //backupVParameters.Add(new List<double>(steps + 1)); //newTabAngles.Add(new List<double>(steps + 1)); for (int j = 0; j <= steps; j++) { // newVParameters[i].Add(vParameters[i][j]); // backupVParameters[i].Add(vParameters[i][j]); //newTabAngles[i].Add(tabAngles[i][j]); } } double cumulativeErrorTally = 0; MaxError = 0; for (int i = 0; i <= steps; i++) { for (int j = 0; j <= steps; j++) { Vector grad = Gradient(points[i, j]); points[i, j] = points[i, j] + grad.Z * Direction.DirZ / 100; #if false bool swap = j % 2 == 0; int iOtherDir = swap ? -1 : 1; int iOther = i + iOtherDir; Circle baseCircle = GetTabFromPoints(true, i, j, iOther); Circle circle0 = GetTabFromPoints(true, iOther, j - 1, i); Circle circle1 = GetTabFromPoints(true, iOther, j + 1, i); double distance0 = (baseCircle.Frame.Origin - circle0.Frame.Origin).Magnitude - baseCircle.Radius - circle0.Radius; double distance1 = (baseCircle.Frame.Origin - circle1.Frame.Origin).Magnitude - baseCircle.Radius - circle1.Radius; cumulativeErrorTally += distance0 * distance0 + distance1 * distance1; MaxError = Math.Max(Math.Abs(distance0), MaxError); MaxError = Math.Max(Math.Abs(distance1), MaxError); double angleAdjust = (distance0 + distance1) / 2 * AngleForce / GetSpanAt(i, j) / baseCircle.Radius; // / GetSpanAt(i, j) / baseCircle.Radius; // / baseCircle.Radius; newTabAngles[i][j] -= angleAdjust; newTabAngles[i][j - 1] -= angleAdjust / 2; newTabAngles[i][j + 1] -= angleAdjust / 2; double iAngle = AddInHelper.AngleBetween( circle0.Frame.Origin - baseCircle.Frame.Origin, circle1.Frame.Origin - baseCircle.Frame.Origin ); double vOffset = (distance1 - distance0) * VForce; //double uAngleOffset = -(Math.PI / 2 - Math.Abs(iAngle)) * UAngleForce; double uAngleOffset = -(Math.PI * 2 / 3 - Math.Abs(iAngle)) * UAngleForce; Circle circleV = GetTabFromPoints(true, iOther, j, i); double distanceV = (baseCircle.Frame.Origin - circleV.Frame.Origin).Magnitude - baseCircle.Radius - circleV.Radius; double uTouchOffset = -distanceV * UTouchForce; double averageOffset = 0; double averageAngle = 0; double count = 0; foreach (int ii in new int[] { i, iOther }) { foreach (int jj in new int[] { j - 1, j + 1 }) { averageAngle += GetTabFromPoints(true, ii, jj, ii == i ? iOther : i).Radius; count++; } } averageOffset += GetSpanAt(i - 1, j); averageOffset += GetSpanAt(i + 1, j); averageOffset += GetSpanAt(i, j - 1); averageOffset += GetSpanAt(i, j + 1); averageOffset /= 4; averageOffset = averageOffset / count - GetSpanAt(i, j); averageOffset *= -AverageVForce / 2; averageAngle = averageAngle / count - baseCircle.Radius; newTabAngles[i][j] -= averageAngle * AverageTabAngleForce; double size = 1; // (points[i][j + 1] - points[i][j]).Magnitude; double slip = (uAngleOffset + averageOffset + uTouchOffset) * size; newVParameters[i][j] += vOffset + slip; newVParameters[i][j + 1] += vOffset - slip; newVParameters[i][j - 1] += (vOffset + slip) / 2; newVParameters[i][j + 2] += (vOffset - slip) / 2; // double oldSpan = (points[i][j + 1] - points[i][j]).Magnitude; // double newSpan = (points[i][j + 1] - points[i][j]).Magnitude; Trace.WriteIf(Iteration % 400 == 0, tabAngles[i][j] + " "); // Trace.WriteIf(Iteration % 400 == 0, iAngle + " "); // Trace.WriteIf(Iteration % 400 == 0, GetSpanAt(i,j) + " "); #endif } Trace.WriteLineIf(Iteration % 400 == 0, ""); } #if false // Average antipodal points // for l(i, j), // l(i, j) == l(-i, pi+j)* == l(i+2pi, -j) == l(-i-2pi, pi-j)* // Where * means x=x, y=-y, z=-z for (int i = 0; i < iSteps; i++) { for (int j = 0; j < jSteps / 2; j++) { double average = ( newVParameters[i][j] + newVParameters[-i][j + jSteps / 2] - Math.PI + (j < 2 ? 0 : 2 * Math.PI) - newVParameters[i + iSteps][-j + 1] + Math.PI - newVParameters[-i - iSteps][-j + jSteps / 2 + 1] ) / 4; newVParameters[i][j] = average; newVParameters[-i][j + jSteps / 2] = average + Math.PI; newVParameters[i + iSteps][-j + 1] = (j < 2 ? 0 : 2 * Math.PI) - average; newVParameters[-i - iSteps][-j + jSteps / 2 + 1] = Math.PI - average; average = ( tabAngles[i][j] + tabAngles[-i][j + jSteps / 2 + 1] + tabAngles[i + iSteps][-j] + tabAngles[-i - iSteps][-j + jSteps / 2 + 1] ) / 4; tabAngles[i][j] = average; tabAngles[-i][j + jSteps / 2 + 1] = average; tabAngles[i + iSteps][-j] = average; tabAngles[-i - iSteps][-j + jSteps / 2 + 1] = average; } } #endif CumulativeError = Math.Sqrt(cumulativeErrorTally / (steps * steps * 2)); // Trace.WriteLine(lastCumulativeError); // We're not calculating the points for the last iteration. Whatevs. // vParameters = newVParameters; //tabAngles = newTabAngles; #if false for (int i = 0; i < iSteps; i++) { double u = 2 * Math.PI * (double)i / iSteps; for (int j = 0; j < jSteps; j++) { points[i][j] = Gyroid.Evaluate(PointUV.Create(vParameters[i][j], u), p, q, circleAngle, inverseOffset, true) * scale; // Trace.WriteLine(string.Format("{0} {1} {2}", i, j, tabAngles[i][j])); } } #endif }
private static double AngleBetween(List <Component> chain, int i) { int numGears = chain.Count; return(AddInHelper.AngleBetween(chain[i].Placement.Translation - chain[(i + 1) % numGears].Placement.Translation, chain[i].Placement.Translation - chain[(i + numGears - 1) % numGears].Placement.Translation)); }
protected override void OnExecute(Command command, ExecutionContext context, System.Drawing.Rectangle buttonRect) { double lengthConversion = ActiveWindow.Units.Length.ConversionFactor; int numberOfTeethL = (int)Values[Resources.NumberOfTeethLText].Value; int numberOfTeethR = (int)Values[Resources.NumberOfTeethRText].Value; bool isInternalL = numberOfTeethL < 0; bool isInternalR = numberOfTeethR < 0; numberOfTeethL = Math.Abs(numberOfTeethL); numberOfTeethR = Math.Abs(numberOfTeethR); double pressureAngle = Values[Resources.PressureAngleText].Value * Math.PI / 180; double module = Values[Resources.ModuleText].Value / lengthConversion; double dedendumClearance = Values[Resources.DedendumClearanceText].Value; double depth = Values[Resources.DepthText].Value / lengthConversion; bool useTrochoidalInterferenceRemoval = Booleans[Resources.UseTrochoidalText].Value; bool addDedendumClearance = Booleans[Resources.AddDedendumClearance].Value; if (!addDedendumClearance) { dedendumClearance = 0; } bool isBevel = RibbonBooleanGroupCapsule.BooleanGroupCapsules[Resources.IsBevelText].IsEnabledCommandBoolean.Value; double bevelAngle = RibbonBooleanGroupCapsule.BooleanGroupCapsules[Resources.IsBevelText].Values[Resources.BevelAngleText].Value * Math.PI / 180; double bevelKneeRatio = RibbonBooleanGroupCapsule.BooleanGroupCapsules[Resources.IsBevelText].Values[Resources.BevelKneeRatioText].Value; bool isHelical = RibbonBooleanGroupCapsule.BooleanGroupCapsules[Resources.IsHelicalText].IsEnabledCommandBoolean.Value; double helicalAngle = RibbonBooleanGroupCapsule.BooleanGroupCapsules[Resources.IsHelicalText].Values[Resources.HelicalAngleText].Value * Math.PI / 180; if (!isHelical) { helicalAngle = 0; } bool isScrew = RibbonBooleanGroupCapsule.BooleanGroupCapsules[Resources.IsScrewText].IsEnabledCommandBoolean.Value; double screwAngle = RibbonBooleanGroupCapsule.BooleanGroupCapsules[Resources.IsScrewText].Values[Resources.ScrewAngleText].Value * Math.PI / 180; double screwAngleOffset = RibbonBooleanGroupCapsule.BooleanGroupCapsules[Resources.IsScrewText].Values[Resources.ScrewAngleBiasText].Value * Math.PI / 180; if (!isScrew) { screwAngle = 0; screwAngleOffset = 0; } double screwAngleAverage = screwAngle / 2; double screwAngleL = screwAngleAverage + screwAngleOffset; double screwAngleR = screwAngleAverage - screwAngleOffset; bool isHypoid = RibbonBooleanGroupCapsule.BooleanGroupCapsules[Resources.IsHypoidText].IsEnabledCommandBoolean.Value; double hypoidAngle = RibbonBooleanGroupCapsule.BooleanGroupCapsules[Resources.IsHypoidText].Values[Resources.HypoidAngleText].Value * Math.PI / 180; double hypoidOffset = RibbonBooleanGroupCapsule.BooleanGroupCapsules[Resources.IsHypoidText].Values[Resources.HypoidOffsetText].Value / lengthConversion; if (!isHypoid) { hypoidAngle = 0; hypoidOffset = 0; } Frame frame = Frame.World; //Circle circle = SelectedCircle(ActiveWindow); //if (circle != null) // frame = circle.Frame; List <ITrimmedCurve> selectedCurves = ActiveWindow.GetAllSelectedITrimmedCurves().ToList(); if (selectedCurves.Count == 2 && selectedCurves[0].Geometry is Circle && selectedCurves[0].Geometry is Circle) { Circle circle0 = (Circle)selectedCurves[0].Geometry; Circle circle1 = (Circle)selectedCurves[1].Geometry; Separation separation = circle0.Axis.GetClosestSeparation(circle1.Axis); if (Accuracy.LengthIsZero(separation.Distance)) { throw new NotImplementedException("Distance between axes is zero; only hypoid implemented."); } isHypoid = true; hypoidAngle = AddInHelper.AngleBetween(circle0.Axis.Direction, circle1.Axis.Direction); hypoidOffset = ((circle0.Frame.Origin - separation.PointA).Magnitude - depth / 2) / Math.Cos(hypoidAngle / 2); double radiusAApprox = separation.Distance * circle0.Radius / (circle0.Radius + circle1.Radius); double radiusBApprox = separation.Distance - radiusAApprox; numberOfTeethR = (int)Math.Round((double)numberOfTeethL / radiusAApprox * radiusBApprox); module = radiusAApprox * 2 / numberOfTeethL; Point midpoint = separation.PointA + (separation.PointA - separation.PointB) * numberOfTeethL / numberOfTeethR; Direction sideSide = (circle0.Frame.Origin - circle1.Frame.Origin).Direction; frame = Frame.Create(midpoint, Direction.Cross(sideSide, -(midpoint - circle0.GetClosestSeparation(circle1).PointA).Direction), sideSide); } double hypoidAngleL = Math.Atan(Math.Sin(hypoidAngle) / (Math.Cos(hypoidAngle) + (double)numberOfTeethR / numberOfTeethL)); double hypoidAngleR = Math.Atan(Math.Sin(hypoidAngle) / (Math.Cos(hypoidAngle) + (double)numberOfTeethL / numberOfTeethR)); Gear gearL = null; Gear gearR = null; var gearDataL = new GearData(numberOfTeethL, pressureAngle, module, dedendumClearance, isInternalL, screwAngleL); var gearDataR = new GearData(numberOfTeethR, pressureAngle, module, dedendumClearance, isInternalR, screwAngleR); ToothProfile toothProfileL = GetGearProfileFromOptions(gearDataL, gearDataR, useTrochoidalInterferenceRemoval, addDedendumClearance); ToothProfile toothProfileR = GetGearProfileFromOptions(gearDataR, gearDataL, useTrochoidalInterferenceRemoval, addDedendumClearance); if (isBevel) { gearL = BevelGear.Create(ActiveIPart, gearDataL, gearDataR, toothProfileL, helicalAngle, bevelAngle, bevelKneeRatio, depth); gearR = BevelGear.Create(ActiveIPart, gearDataR, gearDataL, toothProfileR, -helicalAngle, bevelAngle, bevelKneeRatio, depth); } else if (isHypoid) { gearL = HypoidGear.Create(ActiveIPart, gearDataL, gearDataR, toothProfileL, helicalAngle, hypoidAngleL, hypoidOffset, bevelKneeRatio, depth); gearR = HypoidGear.Create(ActiveIPart, gearDataR, gearDataL, toothProfileR, -helicalAngle, hypoidAngleR, hypoidOffset, bevelKneeRatio, depth); } else { gearL = StraightGear.Create(ActiveIPart, gearDataL, gearDataR, toothProfileL, helicalAngle, screwAngleL, depth); gearR = StraightGear.Create(ActiveIPart, gearDataR, gearDataL, toothProfileR, -helicalAngle, screwAngleR, depth); } Line zAxis = Line.Create(Point.Origin, Direction.DirZ); gearL.Component.Transform( Matrix.CreateMapping(frame) * Matrix.CreateRotation(zAxis, Math.PI) * gearL.TransformToTangent * Matrix.CreateRotation(zAxis, gearDataL.PitchAngle * ((double)1 / 2 + (gearDataL.NumberOfTeeth % 2 == 0 && !isHypoid ? -1 : 0))) ); gearR.Component.Transform( Matrix.CreateMapping(frame) * gearR.TransformToTangent * Matrix.CreateRotation(zAxis, gearDataR.PitchAngle * ((double)1 / 2 + (gearDataR.NumberOfTeeth % 2 == 0 && !isHypoid ? -1 : 0))) ); // if (gearDataR.NumberOfTeeth % 2 == 0) // gearR.Component.Transform(Matrix.CreateRotation(Line.Create(Point.Origin, Direction.DirZ), gearDataR.PitchAngle)); //gearR.Component.Transform(gearR.TransformToTangent); Part parent = ActiveIPart.Master; IDesignFace pitchCircleL = gearL.Component.Content.Bodies.Where(b => b.Master == gearL.PitchCircleDesBody).First().Faces.First(); IDesignFace pitchCircleR = gearR.Component.Content.Bodies.Where(b => b.Master == gearR.PitchCircleDesBody).First().Faces.First(); Part gearMountPart = Part.Create(parent.Document, String.Format(Resources.GearMountPartName, gearDataL.NumberOfTeeth, gearDataR.NumberOfTeeth)); Component gearMountComponent = Component.Create(parent, gearMountPart); DesignBody mountBodyL = DesignBody.Create(gearMountPart, string.Format(Resources.MountBodyName, gearDataL.NumberOfTeeth), pitchCircleL.Master.Shape.Body.CreateTransformedCopy(pitchCircleL.TransformToMaster.Inverse)); DesignBody mountBodyR = DesignBody.Create(gearMountPart, string.Format(Resources.MountBodyName, gearDataR.NumberOfTeeth), pitchCircleR.Master.Shape.Body.CreateTransformedCopy(pitchCircleR.TransformToMaster.Inverse)); IDesignFace mountCircleL = gearMountComponent.Content.Bodies.Where(b => b.Master == mountBodyL).First().Faces.First(); IDesignFace mountCircleR = gearMountComponent.Content.Bodies.Where(b => b.Master == mountBodyR).First().Faces.First(); Layer mountLayer = NoteHelper.CreateOrGetLayer(ActiveDocument, Resources.GearMountAlignmentCircleLayer, System.Drawing.Color.LightGray); mountLayer.SetVisible(null, false); mountBodyL.Layer = mountLayer; mountBodyR.Layer = mountLayer; MatingCondition matingCondition; matingCondition = AnchorCondition.Create(parent, gearMountComponent); matingCondition = AlignCondition.Create(parent, mountCircleL, pitchCircleL); matingCondition = AlignCondition.Create(parent, mountCircleR, pitchCircleR); // matingCondition = TangentCondition.Create(parent, pitchCircleL, pitchCircleR); GearCondition gearCondition = GearCondition.Create(parent, pitchCircleL, pitchCircleR); if (gearDataL.IsInternal ^ gearDataR.IsInternal) { gearCondition.IsBelt = true; } ActiveWindow.InteractionMode = InteractionMode.Solid; Settings.Default.NumberOfTeethL = numberOfTeethL; Settings.Default.NumberOfTeethR = numberOfTeethR; Settings.Default.PressureAngleDegrees = pressureAngle * 180 / Math.PI; Settings.Default.Module = module; Settings.Default.Depth = depth; Settings.Default.DedendumClearance = dedendumClearance; Settings.Default.UseTrochoidalInterferenceRemoval = useTrochoidalInterferenceRemoval; Settings.Default.AddDedendumClearace = addDedendumClearance; Settings.Default.IsBevel = isBevel; if (isBevel) { Settings.Default.BevelAngle = bevelAngle * 180 / Math.PI; Settings.Default.BevelKneeRatio = bevelKneeRatio; } Settings.Default.IsHelical = isHelical; Settings.Default.HelicalAngle = helicalAngle * 180 / Math.PI; Settings.Default.IsScrew = isScrew; Settings.Default.ScrewAngle = screwAngle * 180 / Math.PI; Settings.Default.ScrewAngleOffset = screwAngleOffset * 180 / Math.PI; Settings.Default.IsHypoid = isHypoid; Settings.Default.HypoidAngle = hypoidAngle * 180 / Math.PI; Settings.Default.HypoidOffset = hypoidOffset * lengthConversion; Settings.Default.Save(); }