public void RoutPath(Rout r, bool backwards) { List <Vector2> mine = new List <Vector2>(); foreach (Vector2 p in (r.Points)) { mine.Add(new Vector2(p.X, p.Y)); } if (backwards) { mine.Reverse(); } for (int i = 0; i < mine.Count; i++) { float x = mine[i].X / 1000.0f; float y = mine[i].Y / 1000.0f; float z = r.Depth / 1000.0f; MoveTool m = new MoveTool(new Vector3(x, y, z), rout_speed); if (i == 0) { if ((finalPosition.Xy - m.Location.Xy).Length > .0001) { // Need to move the router up, over to new position, then down again. MoveTool m1 = new MoveTool(new Vector3(finalPosition.X, finalPosition.Y, move_height), move_speed); MoveTool m2 = new MoveTool(new Vector3(m.Location.X, m.Location.Y, move_height), move_speed); AddCommand(m1); AddCommand(m2); } } AddCommand(m); } }
internal Rout Delete() { if (closestIsPoint && closestPoint >= 0 && closestPoint < Points.Count) { Points.RemoveAt(closestPoint); } else if (closestPoint >= 0 && closestPoint < (Points.Count - 1)) { Rout r = new Rout(); for (int i = closestPoint + 1; i < Points.Count; i++) { r.Points.Add(Points[i]); } Points.RemoveRange(closestPoint + 1, r.Points.Count); if (r.Points.Count > 1) { return(r); } } HasChanged = true; return(null); }
public void Parse(string[] lines) { foreach (string s in lines) { Regex r = new Regex("^G(?<G_VALUE>\\d+)"); if (r.IsMatch (s)) { Match m = r.Match(s); Int32 g_value = Int32.Parse (m.Groups["G_VALUE"].Value); if (g_value == 0) { // Rapid Positioning, go to (x, y, z) as fast as possible Vector3 fromPoint = new Vector3(lastx, lasty, lastz); GetFloat(s, "X", ref lastx); GetFloat(s, "Y", ref lasty); GetFloat(s, "Z", ref lastz); Vector3 toPoint = new Vector3(lastx, lasty, lastz); Rout rout = new Rout(); rout.just_moving = true; rout.Width = 5; rout.Points = new List<Vector2>(new Vector2[] { new Vector2(fromPoint.X * 1000, fromPoint.Y * 1000), new Vector2(toPoint.X * 1000, toPoint.Y * 1000) }); rout.Depth = toPoint.Z * 1000; linear_routs.Add(rout); } else if (g_value == 1) { // Linear Interpolation Vector3 fromPoint = new Vector3(lastx, lasty, lastz); GetFloat(s, "X", ref lastx); GetFloat(s, "Y", ref lasty); GetFloat(s, "Z", ref lastz); Vector3 toPoint = new Vector3(lastx, lasty, lastz); Rout rout = new Rout(); rout.Width = 20; rout.Points = new List<Vector2>(new Vector2[] { new Vector2(fromPoint.X * 1000, fromPoint.Y * 1000), new Vector2(toPoint.X * 1000, toPoint.Y * 1000) }); rout.Depth = toPoint.Z * 1000; linear_routs.Add(rout); //Console.WriteLine("From " + fromPoint + " To " + toPoint); } else if (g_value == 4) { // Dwell Time (X, U, or P): dwell time in milliseconds } else if (g_value == 20) { // Inch Mode Console.WriteLine("Units are Inches"); } else if (g_value == 21) { // Metric Mode throw new NotSupportedException("Metric GCode is not supported!"); } else if (g_value == 90) { // Absolute Programming Console.WriteLine("Absolute Programming"); } else { Console.WriteLine("G code is not understood: " + s); } //string groupName = r.GroupNumberFromName("G_VALUE").ToString(); //MatchCollection m = r.Matches; //Console.WriteLine(s + ", Group Name = " + groupName); } } }
internal Rout Delete() { if (closestIsPoint && closestPoint >= 0 && closestPoint < Points.Count) { Points.RemoveAt(closestPoint); } else if (closestPoint >=0 && closestPoint < (Points.Count-1)) { Rout r = new Rout(); for (int i = closestPoint + 1; i < Points.Count; i++) { r.Points.Add(Points[i]); } Points.RemoveRange(closestPoint + 1, r.Points.Count) ; if (r.Points.Count > 1) return r; } HasChanged = true; return null; }
public void RoutPath(Rout r, bool backwards) { List<Vector2> mine = new List<Vector2>(); foreach (Vector2 p in (r.Points)) { mine.Add(new Vector2(p.X, p.Y)); } if (backwards) { mine.Reverse(); } for (int i = 0; i < mine.Count; i++) { float x = mine[i].X / 1000.0f; float y = mine[i].Y / 1000.0f; float z = r.Depth / 1000.0f; MoveTool m = new MoveTool(new Vector3(x, y, z), rout_speed); if (i == 0) { if ((finalPosition.Xy - m.Location.Xy).Length > .0001) { // Need to move the router up, over to new position, then down again. MoveTool m1 = new MoveTool(new Vector3(finalPosition.X, finalPosition.Y, move_height), move_speed); MoveTool m2 = new MoveTool(new Vector3(m.Location.X, m.Location.Y, move_height), move_speed); AddCommand(m1); AddCommand(m2); } } AddCommand(m); } }
private void ComputePoints() { outerRout = new Rout(); outerRout.Width = width; outerRout.Depth = depth; double pitch = 80; double tooth_width = 45; // outside tooth width (part that fits into the pulley) double c = this.teeth * pitch; double r = (c / (2 * Math.PI)); double tr = this.width / 2; // tool radius for (int i = 0; i < this.teeth; i++) { //double pulley_tooth_center = (double)i; double theta_total = ((double)1 / (double)this.teeth) * 2.0 * Math.PI; double theta_b = (tooth_width / pitch) * theta_total; double theta_a = (theta_total - theta_b) / 2.0; double theta_start = (double)i * theta_total; Vector2 a1 = new Vector2((float)(Math.Cos(theta_start) * r), (float)(Math.Sin(theta_start) * r)); Vector2 a2 = new Vector2((float)(Math.Cos(theta_start + theta_a) * r), (float)(Math.Sin(theta_start + theta_a) * r)); Vector2 a3 = new Vector2((float)(Math.Cos(theta_start + theta_a + theta_b) * r), (float)(Math.Sin(theta_start + theta_a + theta_b) * r)); Vector2 a4 = new Vector2((float)(Math.Cos(theta_start + theta_a + theta_b + theta_a) * r), (float)(Math.Sin(theta_start + theta_a + theta_b + theta_a) * r)); double w = (Math.Tan(tooth_taper_angle) * tooth_depth) / pitch * theta_total; Vector2 b1 = new Vector2((float)(Math.Cos(theta_start + theta_a + w) * (r - tooth_depth)), (float)(Math.Sin(theta_start + theta_a + w) * (r - tooth_depth))); Vector2 b2 = new Vector2((float)(Math.Cos(theta_start + theta_a + theta_b - w) * (r - tooth_depth)), (float)(Math.Sin(theta_start + theta_a + theta_b - w) * (r - tooth_depth))); CoolDrawing.DrawLine(1, a2 + this.Center, b1 + this.Center, Color.DarkBlue); CoolDrawing.DrawLine(1, b1 + this.Center, b2 + this.Center, Color.Red); CoolDrawing.DrawLine(1, b2 + this.Center, a3 + this.Center, Color.DarkBlue); CoolDrawing.DrawLine(1, a1 + this.Center, a2 + this.Center, Color.Red); CoolDrawing.DrawLine(1, a3 + this.Center, a4 + this.Center, Color.DarkGreen); Vector2 p = new Vector2((float)(Math.Cos(theta_start) * r), (float)(Math.Sin(theta_start) * r)); CoolDrawing.DrawLine(1, this.Center, p + this.Center, Color.Black); // Tool Path double tw = tr * Math.Tan(0.25 * Math.PI - tooth_taper_angle / 2) / pitch * theta_total; Vector2 t1 = this.Center + new Vector2((float)(Math.Cos(theta_start) * (r + tr)), (float)(Math.Sin(theta_start) * (r + tr))); Vector2 t2 = this.Center + new Vector2((float)(Math.Cos(theta_start + theta_a + tw) * (r + tr)), (float)(Math.Sin(theta_start + theta_a + tw) * (r + tr))); Vector2 t3 = this.Center + new Vector2((float)(Math.Cos(theta_start + theta_a + theta_b - tw) * (r + tr)), (float)(Math.Sin(theta_start + theta_a + theta_b - tw) * (r + tr))); Vector2 t4 = this.Center + new Vector2((float)(Math.Cos(theta_start + theta_a + theta_b + theta_a) * (r + tr)), (float)(Math.Sin(theta_start + theta_a + theta_b + theta_a) * (r + tr))); Vector2 tb1 = this.Center + new Vector2((float)(Math.Cos(theta_start + theta_a + w + tw) * (r - tooth_depth + tr)), (float)(Math.Sin(theta_start + theta_a + w + tw) * (r - tooth_depth + tr))); Vector2 tb2 = this.Center + new Vector2((float)(Math.Cos(theta_start + theta_a + theta_b - w - tw) * (r - tooth_depth + tr)), (float)(Math.Sin(theta_start + theta_a + theta_b - w - tw) * (r - tooth_depth + tr))); //CoolDrawing.DrawLine((float)tr * 2, t1 + this.center, t2 + this.center, toolColor); //CoolDrawing.DrawLine((float)tr * 2, t2 + this.center, tb1 + this.center, toolColor); //CoolDrawing.DrawLine((float)tr * 2, tb1 + this.center, tb2 + this.center, toolColor); //CoolDrawing.DrawLine((float)tr * 2, tb2 + this.center, t3 + this.center, toolColor); //CoolDrawing.DrawLine((float)tr * 2, t3 + this.center, t4 + this.center, toolColor); outerRout.Points.Add(new Vector2(t1.X, t1.Y)); outerRout.Points.Add(new Vector2(t2.X, t2.Y)); outerRout.Points.Add(new Vector2(tb1.X, tb1.Y)); outerRout.Points.Add(new Vector2(tb2.X, tb2.Y)); outerRout.Points.Add(new Vector2(t3.X, t3.Y)); outerRout.Points.Add(new Vector2(t4.X, t4.Y)); } innerRout = new Rout(); innerRout.Width = width; innerRout.Depth = center_hole_depth; float circumference = (float)Math.PI * 2 * radius; //int _pointCount = pointCount; //if (_pointCount <= 1) //{ int _pointCount = (int)(0.5f * circumference / width); if (_pointCount <= 12) { _pointCount = 12; } for (int i = 0; i <= _pointCount; i++) { Vector2 p = new Vector2((float)(Math.Cos(Math.PI * 2 * i / _pointCount) * (radius - tr)), (float)(Math.Sin(Math.PI * 2 * i / _pointCount) * (radius - tr))); p += Center; innerRout.Points.Add(new Vector2(p.X, p.Y)); } //base.HasChanged = true; }
private void ComputePoints() { float contact_circumference = circular_pitch * teeth; double contact_radius = contact_circumference / (Math.PI * 2); double base_radius = contact_radius * Cosd(pressure_angle); double outer_radius = contact_radius + addendum; double inner_radius = contact_radius - dedendum; double theta_to_contact_radius = Degrees(Sind(pressure_angle) / Cosd(pressure_angle)); List <Rout> Routs = new List <Rout>(); float a_radians = (float)(Math.PI * (0 - (theta_to_contact_radius - pressure_angle)) / 180.0f); // Create routs to match the drawn line Rout rt = new Rout(); rt.Width = this.width; // Line from inner radius to start of base circle double sin_theta = (float)Math.Sin(a_radians); double cos_theta = (float)Math.Cos(a_radians); // Tails into gear for dedendum if (inner_radius < base_radius) { Vector2 radial = new Vector2((float)cos_theta, (float)sin_theta); Vector2 tangential = new Vector2((float)sin_theta, (float)(-cos_theta)); tangential = radial.PerpendicularRight; rt.Points.Add(Vector2.Multiply(tangential, rt.Width / 2) + Center + Vector2.Multiply(radial, (float)(inner_radius + rt.Width / 2))); rt.Points.Add(Vector2.Multiply(tangential, rt.Width / 2) + Center + Vector2.Multiply(radial, (float)base_radius)); } // Degrees to rotate while drawing involute curve from base_radius to outer_radius float distance = (float)Degrees(Math.Sqrt(outer_radius * outer_radius - base_radius * base_radius) / base_radius); for (double theta = 0; theta <= distance; theta += 3.0f / Sind(theta + 15)) { Vector2 routPoint = ComputeInvolutePoint(theta, Degrees(a_radians), base_radius, rt.Width / 2); rt.Points.Add(Center + routPoint); } Vector2 lastDirection = ComputeInvolutePoint(distance, Degrees(a_radians), base_radius, rt.Width / 2); rt.Points.Add(Center + lastDirection); lastDirection = Vector2.Normalize(lastDirection); float spacing_degrees = 360 / teeth; float d2 = (float)(outer_radius + rt.Width / 2); Vector2 radial2 = new Vector2( (float)Cosd(spacing_degrees / 4), (float)Sind(spacing_degrees / 4)); rt.Points.Add(Center + Vector2.Multiply(lastDirection, d2)); // Flip the points in rt about the line radial2 List <Vector2> back = new List <Vector2>(); foreach (Vector2 v in rt.Points) { Vector2 original = v - Center; float parallel = Vector2.Dot(radial2, original); float perpendicular = Vector2.Dot(radial2.PerpendicularRight, original); Vector2 result = Vector2.Multiply(radial2, parallel) + Vector2.Multiply(radial2.PerpendicularRight, -perpendicular); back.Insert(0, result + Center); } foreach (Vector2 p in back) { rt.Points.Add(p); } Rout rout = new Rout(); rout.Width = rt.Width; for (int tooth = 0; tooth < teeth; tooth++) { Quaternion q = Quaternion.FromAxisAngle(new Vector3(0, 0, 1), tooth * OpenTK.MathHelper.TwoPi / (float)teeth + (float)Radians(base_rotation)); foreach (Vector2 v in rt.Points) { Vector2 original = v - Center; Vector2 result = Vector2.Transform(original, q); rout.Points.Add(result + Center); } } // And back to the first point! TODO: Rotate this point too... rout.Points.Add(rt.Points[0]); this.outerRout = rout; outerRout.Depth = this.depth; innerRout = new Rout(); innerRout.Width = width; innerRout.Depth = center_hole_depth; float circumference = (float)Math.PI * 2 * radius; //int _pointCount = pointCount; //if (_pointCount <= 1) //{ int _pointCount = (int)(0.5f * circumference / width); if (_pointCount <= 12) { _pointCount = 12; } float tr = width / 2; for (int i = 0; i <= _pointCount; i++) { Vector2 p = new Vector2((float)(Math.Cos(Math.PI * 2 * i / _pointCount) * (radius - tr)), (float)(Math.Sin(Math.PI * 2 * i / _pointCount) * (radius - tr))); p += Center; innerRout.Points.Add(new Vector2(p.X, p.Y)); } //base.HasChanged = true; }
public void Draw() { float contact_circumference = circular_pitch * teeth; double contact_radius = contact_circumference / (Math.PI * 2); double base_radius = contact_radius * Cosd(pressure_angle); double outer_radius = contact_radius + addendum; double inner_radius = contact_radius - dedendum; CoolDrawing.DrawCircle((float)base_radius, Center, Color.Black); CoolDrawing.DrawCircle((float)contact_radius, Center, Color.Orange); CoolDrawing.DrawCircle((float)outer_radius, Center, Color.DarkBlue); CoolDrawing.DrawCircle((float)inner_radius, Center, Color.DarkBlue); double theta_to_contact_radius = Degrees(Sind(pressure_angle) / Cosd(pressure_angle)); List <Rout> Routs = new List <Rout>(); float a_radians = (float)(Math.PI * (0 - (theta_to_contact_radius - pressure_angle)) / 180.0f); // Draw an involute curve off the surface of the gear GL.Begin(BeginMode.LineStrip); GL.Color3(Color.Black); // Create routs to match the drawn line Rout rt = new Rout(); rt.Width = this.width; // Line from inner radius to start of base circle double sin_theta = (float)Math.Sin(a_radians); double cos_theta = (float)Math.Cos(a_radians); if (inner_radius < base_radius) { double x = inner_radius * cos_theta + this.X; double y = inner_radius * sin_theta + this.Y; GL.Vertex2(x, y); x = base_radius * cos_theta + this.X; y = base_radius * sin_theta + this.Y; GL.Vertex2(x, y); } // Degrees to rotate while drawing involute curve from base_radius to outer_radius float distance = (float)Degrees(Math.Sqrt(outer_radius * outer_radius - base_radius * base_radius) / base_radius); // Draw an involute line from base_radius to outer_radius for (double theta = 0; theta <= (distance + .0001); theta += (distance / 20.0f)) { Vector2 point = ComputeInvolutePoint(theta, Degrees(a_radians), base_radius, 0); GL.Vertex2(point + Center); } GL.End(); //outerRout.Draw(); foreach (Rout a in this.GetRouts()) { a.Draw(); } }
public void Parse(string[] lines) { foreach (string s in lines) { Regex r = new Regex("^G(?<G_VALUE>\\d+)"); if (r.IsMatch(s)) { Match m = r.Match(s); Int32 g_value = Int32.Parse(m.Groups["G_VALUE"].Value); if (g_value == 0) { // Rapid Positioning, go to (x, y, z) as fast as possible Vector3 fromPoint = new Vector3(lastx, lasty, lastz); GetFloat(s, "X", ref lastx); GetFloat(s, "Y", ref lasty); GetFloat(s, "Z", ref lastz); Vector3 toPoint = new Vector3(lastx, lasty, lastz); Rout rout = new Rout(); rout.just_moving = true; rout.Width = 5; rout.Points = new List <Vector2>(new Vector2[] { new Vector2(fromPoint.X * 1000, fromPoint.Y * 1000), new Vector2(toPoint.X * 1000, toPoint.Y * 1000) }); rout.Depth = toPoint.Z * 1000; linear_routs.Add(rout); } else if (g_value == 1) { // Linear Interpolation Vector3 fromPoint = new Vector3(lastx, lasty, lastz); GetFloat(s, "X", ref lastx); GetFloat(s, "Y", ref lasty); GetFloat(s, "Z", ref lastz); Vector3 toPoint = new Vector3(lastx, lasty, lastz); Rout rout = new Rout(); rout.Width = 20; rout.Points = new List <Vector2>(new Vector2[] { new Vector2(fromPoint.X * 1000, fromPoint.Y * 1000), new Vector2(toPoint.X * 1000, toPoint.Y * 1000) }); rout.Depth = toPoint.Z * 1000; linear_routs.Add(rout); //Console.WriteLine("From " + fromPoint + " To " + toPoint); } else if (g_value == 4) { // Dwell Time (X, U, or P): dwell time in milliseconds } else if (g_value == 20) { // Inch Mode Console.WriteLine("Units are Inches"); } else if (g_value == 21) { // Metric Mode throw new NotSupportedException("Metric GCode is not supported!"); } else if (g_value == 90) { // Absolute Programming Console.WriteLine("Absolute Programming"); } else { Console.WriteLine("G code is not understood: " + s); } //string groupName = r.GroupNumberFromName("G_VALUE").ToString(); //MatchCollection m = r.Matches; //Console.WriteLine(s + ", Group Name = " + groupName); } } }
private void ComputePoints() { float contact_circumference = circular_pitch * teeth; double contact_radius = contact_circumference / (Math.PI * 2); double base_radius = contact_radius * Cosd(pressure_angle); double outer_radius = contact_radius + addendum; double inner_radius = contact_radius - dedendum; double theta_to_contact_radius = Degrees(Sind(pressure_angle) / Cosd(pressure_angle)); List<Rout> Routs = new List<Rout>(); float a_radians = (float)(Math.PI * (0 - (theta_to_contact_radius - pressure_angle)) / 180.0f); // Create routs to match the drawn line Rout rt = new Rout(); rt.Width = this.width; // Line from inner radius to start of base circle double sin_theta = (float)Math.Sin(a_radians); double cos_theta = (float)Math.Cos(a_radians); // Tails into gear for dedendum if (inner_radius < base_radius) { Vector2 radial = new Vector2((float)cos_theta, (float)sin_theta); Vector2 tangential = new Vector2((float)sin_theta, (float)(-cos_theta)); tangential = radial.PerpendicularRight; rt.Points.Add(Vector2.Multiply(tangential, rt.Width / 2) + Center + Vector2.Multiply(radial, (float)(inner_radius + rt.Width / 2))); rt.Points.Add(Vector2.Multiply(tangential, rt.Width / 2) + Center + Vector2.Multiply(radial, (float)base_radius)); } // Degrees to rotate while drawing involute curve from base_radius to outer_radius float distance = (float)Degrees(Math.Sqrt(outer_radius * outer_radius - base_radius * base_radius) / base_radius); for (double theta = 0; theta <= distance; theta += 3.0f/Sind(theta + 15)) { Vector2 routPoint = ComputeInvolutePoint(theta, Degrees(a_radians), base_radius, rt.Width / 2); rt.Points.Add(Center + routPoint); } Vector2 lastDirection = ComputeInvolutePoint(distance, Degrees(a_radians), base_radius, rt.Width / 2); rt.Points.Add(Center + lastDirection); lastDirection = Vector2.Normalize(lastDirection); float spacing_degrees = 360 / teeth; float d2 = (float)(outer_radius + rt.Width / 2); Vector2 radial2 = new Vector2( (float)Cosd(spacing_degrees / 4), (float)Sind(spacing_degrees / 4)); rt.Points.Add(Center + Vector2.Multiply(lastDirection, d2)); // Flip the points in rt about the line radial2 List<Vector2> back = new List<Vector2>(); foreach (Vector2 v in rt.Points) { Vector2 original = v - Center; float parallel = Vector2.Dot(radial2, original); float perpendicular = Vector2.Dot(radial2.PerpendicularRight, original); Vector2 result = Vector2.Multiply(radial2, parallel) + Vector2.Multiply(radial2.PerpendicularRight, -perpendicular); back.Insert(0, result + Center); } foreach (Vector2 p in back) { rt.Points.Add(p); } Rout rout = new Rout(); rout.Width = rt.Width; for (int tooth = 0; tooth < teeth; tooth++) { Quaternion q = Quaternion.FromAxisAngle(new Vector3(0, 0, 1), tooth * OpenTK.MathHelper.TwoPi / (float)teeth + (float)Radians(base_rotation)); foreach (Vector2 v in rt.Points) { Vector2 original = v - Center; Vector2 result = Vector2.Transform(original, q); rout.Points.Add(result + Center); } } // And back to the first point! TODO: Rotate this point too... rout.Points.Add(rt.Points[0]); this.outerRout = rout; outerRout.Depth = this.depth; innerRout = new Rout(); innerRout.Width = width; innerRout.Depth = center_hole_depth; float circumference = (float)Math.PI * 2 * radius; //int _pointCount = pointCount; //if (_pointCount <= 1) //{ int _pointCount = (int)(0.5f * circumference / width); if (_pointCount <= 12) { _pointCount = 12; } float tr = width / 2; for (int i = 0; i <= _pointCount; i++) { Vector2 p = new Vector2((float)(Math.Cos(Math.PI * 2 * i / _pointCount) * (radius - tr)), (float)(Math.Sin(Math.PI * 2 * i / _pointCount) * (radius - tr))); p += Center; innerRout.Points.Add(new Vector2(p.X, p.Y)); } //base.HasChanged = true; }
public void Draw() { float contact_circumference = circular_pitch * teeth; double contact_radius = contact_circumference / (Math.PI * 2); double base_radius = contact_radius * Cosd(pressure_angle); double outer_radius = contact_radius + addendum; double inner_radius = contact_radius - dedendum; CoolDrawing.DrawCircle((float)base_radius, Center, Color.Black); CoolDrawing.DrawCircle((float)contact_radius, Center, Color.Orange); CoolDrawing.DrawCircle((float)outer_radius, Center, Color.DarkBlue); CoolDrawing.DrawCircle((float)inner_radius, Center, Color.DarkBlue); double theta_to_contact_radius = Degrees(Sind(pressure_angle) / Cosd(pressure_angle)); List<Rout> Routs = new List<Rout>(); float a_radians = (float)(Math.PI * (0 - (theta_to_contact_radius - pressure_angle)) / 180.0f); // Draw an involute curve off the surface of the gear GL.Begin(BeginMode.LineStrip); GL.Color3(Color.Black); // Create routs to match the drawn line Rout rt = new Rout(); rt.Width = this.width; // Line from inner radius to start of base circle double sin_theta = (float)Math.Sin(a_radians); double cos_theta = (float)Math.Cos(a_radians); if (inner_radius < base_radius) { double x = inner_radius * cos_theta + this.X; double y = inner_radius * sin_theta + this.Y; GL.Vertex2(x, y); x = base_radius * cos_theta + this.X; y = base_radius * sin_theta + this.Y; GL.Vertex2(x, y); } // Degrees to rotate while drawing involute curve from base_radius to outer_radius float distance = (float)Degrees(Math.Sqrt(outer_radius * outer_radius - base_radius * base_radius) / base_radius); // Draw an involute line from base_radius to outer_radius for (double theta = 0; theta <= (distance + .0001); theta += (distance / 20.0f)) { Vector2 point = ComputeInvolutePoint(theta, Degrees(a_radians), base_radius, 0); GL.Vertex2(point + Center); } GL.End(); //outerRout.Draw(); foreach (Rout a in this.GetRouts()) { a.Draw(); } }