/// <summary> /// Calculates the Machine cost for cutting the parts straight (LineSegment) edges /// </summary> /// <param name="ObjProfile"></param> /// <returns></returns> public double getStraightEdgeCuttingCost(ObjectProfile ObjProfile) { // ... the total perimeter length of the profile double lengthCuttingCost = 0.0; // ... loop through all edges and calculate cutting cost for the LineSegment edge type for (int i = 0; i < ObjProfile.Edges.Count; i++) { // ... get this Edge Type string str = ObjProfile.Edges[i].edgedata.Type; if (str.CompareTo("LineSegment") == 0) { // ... get the X and Y vertices using the pointer for the start position List <double> positionStart = getCoordinatesAt(ObjProfile, ObjProfile.Edges[i].edgedata.Start); // ... get the X and Y vertices using the pointer for the end position List <double> positionEnd = getCoordinatesAt(ObjProfile, ObjProfile.Edges[i].edgedata.End); // ... get the length of this edge (simple Pythagorean Theorem) double A = positionEnd[0] - positionStart[0]; double B = positionEnd[1] - positionStart[1]; double length = Math.Sqrt((A * A) + (B * B)); // ... claculate the cost for this edge lengthCuttingCost += (length / v_max) * MachineTimeCost; } } return(lengthCuttingCost); }
/// <summary> /// Calculates the material size for costing /// </summary> /// <param name="ObjProfile"></param> /// <returns></returns> private static double[] getMaterialSize(ObjectProfile ObjProfile) { // ... container to hole the object x and y dimensions double[] size = new double[2]; // ... container to hold all points for this profile List <PointF> points = new List <PointF>(); // ... first store all vertices in the points collection for (int i = 0; i < ObjProfile.Vertices.Count; i++) { // ... get the point at this location PointF pt = new PointF((float)ObjProfile.Vertices[i].X, (float)ObjProfile.Vertices[i].Y); // ... save it to the points list points.Add(pt); } // ... calculate the midpoint of all Arcs getMidPointOfAllArcs(points, ObjProfile); // ... we now have enough points to calculate the bounding box of this part size = calculateBoundingBox(points); // ... return the values return(size); }
/// <summary> /// Calculates the midpoint of all CircularArcs relative to the Arcs start position and /// clockwise direction. These points are used to help calculate the parts material size. /// </summary> /// <param name="points"></param> /// <param name="ObjProfile"></param> private static void getMidPointOfAllArcs(List <PointF> points, ObjectProfile ObjProfile) { // ... loop through each edge and scan for CircularArc's for (int i = 0; i < ObjProfile.Edges.Count; i++) { // ... get this Edge Type string str = ObjProfile.Edges[i].edgedata.Type; // ... we are only interested in Arcs at this point if (str.CompareTo("CircularArc") == 0) { // ... get the X and Y vertices using the pointer for the start position List <double> positionStart = getCoordinatesAt(ObjProfile, ObjProfile.Edges[i].edgedata.Start); // ... get the X and Y vertices using the pointer for the end position List <double> positionEnd = getCoordinatesAt(ObjProfile, ObjProfile.Edges[i].edgedata.End); // ... the Arc may not always be 180 degrees, so calculate the arc length double[] Vec1 = new double[3] { (positionEnd[0] - ObjProfile.Edges[i].edgedata.CenterX), (positionEnd[1] - ObjProfile.Edges[i].edgedata.CenterY), 0.0 }; double[] Vec2 = new double[3] { (positionStart[0] - ObjProfile.Edges[i].edgedata.CenterX), (positionStart[1] - ObjProfile.Edges[i].edgedata.CenterY), 0.0 }; // ... normilize the vectors Vec1 = Normalize(Vec1); Vec2 = Normalize(Vec2); // ... calculate the angle between the vectors (in radians) double angle = Math.Acos(DotProduct(Vec1, Vec2) / (getVectorLength(Vec1) * getVectorLength(Vec2))); // ... get the point we want to rotate List <double> clockWiseFrom = getCoordinatesAt(ObjProfile, ObjProfile.Edges[i].edgedata.ClockWiseFrom); // ... convert the clockWiseFrom double[] p = new double[3] { clockWiseFrom[0], clockWiseFrom[1], 0.0 }; // ... center point to rotate about double[] p2 = new double[3] { ObjProfile.Edges[i].edgedata.CenterX, ObjProfile.Edges[i].edgedata.CenterY, 0.0 }; // ... rotate point p about the Z-Axis relative to the midpoint of the arc double[] rotationPoint = rotateAboutZ_Axis(p, (angle * 0.5), p2); // ... convert to the PointF type PointF pt = new PointF((float)rotationPoint[0], (float)rotationPoint[1]); // ... save it to the list points.Add(pt); } } }
/// <summary> /// Calculates the material cost for this part /// </summary> /// <param name="ObjProfile"></param> /// <returns></returns> public double getMaterialCost(ObjectProfile ObjProfile) { // ... the size of the profile to be cut (x and y dimensions) double[] size = new double[2]; // ... determine material size size = getMaterialSize(ObjProfile); // ... add padding to the size for the kerf offset size[0] += Padding; size[1] += Padding; // ... return the calculate the cost return((size[0] * size[1]) * MaterialCost); }
/// <summary> /// Calculate the cutting cost for all CircularArc's in this profile /// </summary> /// <param name="ObjProfile"></param> /// <returns></returns> public double getArcCuttingCost(ObjectProfile ObjProfile) { // ... the total perimeter length of the profile double ArcCuttingCost = 0.0; for (int i = 0; i < ObjProfile.Edges.Count; i++) { // ... get this Edge Type string str = ObjProfile.Edges[i].edgedata.Type; // ... we are only interested in Arcs at this point if (str.CompareTo("CircularArc") == 0) { // ... get the X and Y vertices using the pointer for the start position List <double> positionStart = getCoordinatesAt(ObjProfile, ObjProfile.Edges[i].edgedata.Start); // ... get the X and Y vertices using the pointer for the end position List <double> positionEnd = getCoordinatesAt(ObjProfile, ObjProfile.Edges[i].edgedata.End); // ... the Arc may not always be 180 degrees, so calculate the arc length double[] Vec1 = new double[3] { (positionEnd[0] - ObjProfile.Edges[i].edgedata.CenterX), (positionEnd[1] - ObjProfile.Edges[i].edgedata.CenterY), 0.0 }; double[] Vec2 = new double[3] { (positionStart[0] - ObjProfile.Edges[i].edgedata.CenterX), (positionStart[1] - ObjProfile.Edges[i].edgedata.CenterY), 0.0 }; // ... get the radius from this vector (before its normalize) double Radius = getVectorLength(Vec1); // ... normilize the vectors Vec1 = Normalize(Vec1); Vec2 = Normalize(Vec2); // ... calculate the angle between the vectors (in radians) double angle = Math.Acos(DotProduct(Vec1, Vec2) / (getVectorLength(Vec1) * getVectorLength(Vec2))); // ... calculate the arc cutting cost = $((ArcLength / (v_max * exp(-1/R))) * Machine Time Cost) ArcCuttingCost += ((angle * Radius) / (v_max * Math.Exp(-1 / Radius))) * MachineTimeCost; } } return(ArcCuttingCost); }
/// <summary> /// Returns the coordinates in the ObjectProfile pointed to by ptr /// </summary> /// <param name="profile"></param> /// <param name="ptr"></param> /// <returns></returns> private static List <double> getCoordinatesAt(ObjectProfile profile, int ptr) { // ... container to hold both x and y coordinates List <double> pos = new List <double>(); // ... find the vertex we are after for (int i = 0; i < profile.Vertices.Count; i++) { // ... does the Id match ptr if (profile.Vertices[i].Id == ptr) { // ... save the coordinates, x then y pos.Add(profile.Vertices[i].X); pos.Add(profile.Vertices[i].Y); // ... we have the values, break the loop break; } } // ... return the result return(pos); }
/// <summary> /// Calculates the midpoint of all CircularArcs relative to the Arcs start position and /// clockwise direction. These points are used to help calculate the parts material size. /// </summary> /// <param name="points"></param> /// <param name="ObjProfile"></param> private static void getMidPointOfAllArcs(List<PointF> points, ObjectProfile ObjProfile) { // ... loop through each edge and scan for CircularArc's for (int i = 0; i < ObjProfile.Edges.Count; i++) { // ... get this Edge Type string str = ObjProfile.Edges[i].edgedata.Type; // ... we are only interested in Arcs at this point if (str.CompareTo("CircularArc") == 0) { // ... get the X and Y vertices using the pointer for the start position List<double> positionStart = getCoordinatesAt(ObjProfile, ObjProfile.Edges[i].edgedata.Start); // ... get the X and Y vertices using the pointer for the end position List<double> positionEnd = getCoordinatesAt(ObjProfile, ObjProfile.Edges[i].edgedata.End); // ... the Arc may not always be 180 degrees, so calculate the arc length double[] Vec1 = new double[3] { (positionEnd[0] - ObjProfile.Edges[i].edgedata.CenterX), (positionEnd[1] - ObjProfile.Edges[i].edgedata.CenterY), 0.0 }; double[] Vec2 = new double[3] { (positionStart[0] - ObjProfile.Edges[i].edgedata.CenterX), (positionStart[1] - ObjProfile.Edges[i].edgedata.CenterY), 0.0 }; // ... normilize the vectors Vec1 = Normalize(Vec1); Vec2 = Normalize(Vec2); // ... calculate the angle between the vectors (in radians) double angle = Math.Acos(DotProduct(Vec1, Vec2) / (getVectorLength(Vec1) * getVectorLength(Vec2))); // ... get the point we want to rotate List<double> clockWiseFrom = getCoordinatesAt(ObjProfile, ObjProfile.Edges[i].edgedata.ClockWiseFrom); // ... convert the clockWiseFrom double[] p = new double[3] { clockWiseFrom[0], clockWiseFrom[1], 0.0 }; // ... center point to rotate about double[] p2 = new double[3] { ObjProfile.Edges[i].edgedata.CenterX, ObjProfile.Edges[i].edgedata.CenterY, 0.0 }; // ... rotate point p about the Z-Axis relative to the midpoint of the arc double[] rotationPoint = rotateAboutZ_Axis(p, (angle * 0.5), p2); // ... convert to the PointF type PointF pt = new PointF((float)rotationPoint[0], (float)rotationPoint[1]); // ... save it to the list points.Add(pt); } } }
/// <summary> /// Calculates the material size for costing /// </summary> /// <param name="ObjProfile"></param> /// <returns></returns> private static double[] getMaterialSize(ObjectProfile ObjProfile) { // ... container to hole the object x and y dimensions double[] size = new double[2]; // ... container to hold all points for this profile List<PointF> points = new List<PointF>(); // ... first store all vertices in the points collection for (int i = 0; i < ObjProfile.Vertices.Count; i++) { // ... get the point at this location PointF pt = new PointF((float)ObjProfile.Vertices[i].X, (float)ObjProfile.Vertices[i].Y); // ... save it to the points list points.Add(pt); } // ... calculate the midpoint of all Arcs getMidPointOfAllArcs(points, ObjProfile); // ... we now have enough points to calculate the bounding box of this part size = calculateBoundingBox(points); // ... return the values return size; }
/// <summary> /// Returns the coordinates in the ObjectProfile pointed to by ptr /// </summary> /// <param name="profile"></param> /// <param name="ptr"></param> /// <returns></returns> private static List<double> getCoordinatesAt(ObjectProfile profile, int ptr) { // ... container to hold both x and y coordinates List<double> pos = new List<double>(); // ... find the vertex we are after for (int i = 0; i < profile.Vertices.Count; i++) { // ... does the Id match ptr if (profile.Vertices[i].Id == ptr) { // ... save the coordinates, x then y pos.Add(profile.Vertices[i].X); pos.Add(profile.Vertices[i].Y); // ... we have the values, break the loop break; } } // ... return the result return pos; }
/// <summary> /// Calculates the Machine cost for cutting the parts straight (LineSegment) edges /// </summary> /// <param name="ObjProfile"></param> /// <returns></returns> public double getStraightEdgeCuttingCost(ObjectProfile ObjProfile) { // ... the total perimeter length of the profile double lengthCuttingCost = 0.0; // ... loop through all edges and calculate cutting cost for the LineSegment edge type for (int i = 0; i < ObjProfile.Edges.Count; i++) { // ... get this Edge Type string str = ObjProfile.Edges[i].edgedata.Type; if (str.CompareTo("LineSegment") == 0) { // ... get the X and Y vertices using the pointer for the start position List<double> positionStart = getCoordinatesAt(ObjProfile, ObjProfile.Edges[i].edgedata.Start); // ... get the X and Y vertices using the pointer for the end position List<double> positionEnd = getCoordinatesAt(ObjProfile, ObjProfile.Edges[i].edgedata.End); // ... get the length of this edge (simple Pythagorean Theorem) double A = positionEnd[0] - positionStart[0]; double B = positionEnd[1] - positionStart[1]; double length = Math.Sqrt((A * A) + (B * B)); // ... claculate the cost for this edge lengthCuttingCost += (length / v_max) * MachineTimeCost; } } return lengthCuttingCost; }
/// <summary> /// Calculates the material cost for this part /// </summary> /// <param name="ObjProfile"></param> /// <returns></returns> public double getMaterialCost(ObjectProfile ObjProfile) { // ... the size of the profile to be cut (x and y dimensions) double[] size = new double[2]; // ... determine material size size = getMaterialSize(ObjProfile); // ... add padding to the size for the kerf offset size[0] += Padding; size[1] += Padding; // ... return the calculate the cost return ((size[0] * size[1]) * MaterialCost); }
/// <summary> /// Calculate the cutting cost for all CircularArc's in this profile /// </summary> /// <param name="ObjProfile"></param> /// <returns></returns> public double getArcCuttingCost(ObjectProfile ObjProfile) { // ... the total perimeter length of the profile double ArcCuttingCost = 0.0; for (int i = 0; i < ObjProfile.Edges.Count; i++) { // ... get this Edge Type string str = ObjProfile.Edges[i].edgedata.Type; // ... we are only interested in Arcs at this point if (str.CompareTo("CircularArc") == 0) { // ... get the X and Y vertices using the pointer for the start position List<double> positionStart = getCoordinatesAt(ObjProfile, ObjProfile.Edges[i].edgedata.Start); // ... get the X and Y vertices using the pointer for the end position List<double> positionEnd = getCoordinatesAt(ObjProfile, ObjProfile.Edges[i].edgedata.End); // ... the Arc may not always be 180 degrees, so calculate the arc length double[] Vec1 = new double[3] { (positionEnd[0] - ObjProfile.Edges[i].edgedata.CenterX), (positionEnd[1] - ObjProfile.Edges[i].edgedata.CenterY), 0.0 }; double[] Vec2 = new double[3] { (positionStart[0] - ObjProfile.Edges[i].edgedata.CenterX), (positionStart[1] - ObjProfile.Edges[i].edgedata.CenterY), 0.0}; // ... get the radius from this vector (before its normalize) double Radius = getVectorLength(Vec1); // ... normilize the vectors Vec1 = Normalize(Vec1); Vec2 = Normalize(Vec2); // ... calculate the angle between the vectors (in radians) double angle = Math.Acos(DotProduct(Vec1, Vec2) / (getVectorLength(Vec1) * getVectorLength(Vec2))); // ... calculate the arc cutting cost = $((ArcLength / (v_max * exp(-1/R))) * Machine Time Cost) ArcCuttingCost += ((angle * Radius) / (v_max * Math.Exp(-1 / Radius))) * MachineTimeCost; } } return ArcCuttingCost; }