static public PointCollection ParallelShape(PointCollection points, double offset, bool inside = false) { double leftAngle = 0, rightAngle = 0; GeometryOperations.ComputeAngles(points, ref leftAngle, ref rightAngle); bool doLeft = false; if (leftAngle < rightAngle && inside) { doLeft = true; } else if (leftAngle > rightAngle && !inside) { doLeft = true; } if (!doLeft) { offset = -offset; } PointCollection result = new PointCollection(); // Prime the pipeline with the last two non-duplicated points Point p1 = points[points.Count - 2]; Point p2 = points[points.Count - 3]; Point l1a = new Point(); Point l1b = new Point(); Point l2a = new Point(); Point l2b = new Point(); Point newPoint = new Point(); foreach (Point p in points) { if (!Double.IsNaN(p1.X)) { GeometryOperations.OffsetLine(p2, p1, offset, ref l1a, ref l1b); GeometryOperations.OffsetLine(p1, p, offset, ref l2a, ref l2b); newPoint = GeometryOperations.Intersection(l1a, l1b, l2a, l2b); result.Add(newPoint); } p2 = p1; p1 = p; } return(result); }
protected void Panelize(Point3DCollection chine1, Point3DCollection chine2) { double r1, r2; Point intersection_a1, intersection_a2; Point intersection_b1, intersection_b2; PointCollection edge2 = new PointCollection(); m_panelPoints = new PointCollection(); // See if we start at a point or an edge: if ((chine1[0] - chine2[0]).Length < MIN_EDGE_LENGTH) { // Not implemented yet throw new Exception(); //// Start both edges at (0,0) //m_panelPoints.Add(new Point(0, 0)); //edge2.Add(new Point(0, 0)); //// Compute next point, and place it on the x axis //// advance edge1 by one point //r1 = (chine1[0] - chine1[1]).Length; //m_panelPoints.Add(new Point(r1, 0)); //// advance edge2 by one point //r1 = (chine2[0] - chine2[1]).Length; //r2 = (chine1[0] - chine2[1]).Length; //Geometry.Intersection(edge2[edge2.Count - 1], r1, m_panelPoints[m_panelPoints.Count - 1], r2, out intersection_b1, out intersection_b2); //if (intersection_b1.X >= intersection_b2.X) // edge2.Add(intersection_b1); //else // edge2.Add(intersection_b2); } else { // Make the edge the first segment in edge2 m_panelPoints.Add(new Point(0, 0)); edge2.Add(new Point(0, 0)); r1 = (chine1[0] - chine2[0]).Length; edge2.Add(new Point(0, -r1)); // Compute next point, and favor positive X direction // advance edge1 by one point r1 = (chine1[0] - chine1[1]).Length; r2 = (chine2[0] - chine1[1]).Length; GeometryOperations.Intersection(m_panelPoints[m_panelPoints.Count - 1], r1, edge2[edge2.Count - 1], r2, out intersection_a1, out intersection_a2); // advance edge2 by one point r1 = (chine2[0] - chine2[1]).Length; r2 = (chine1[0] - chine2[1]).Length; GeometryOperations.Intersection(edge2[edge2.Count - 1], r1, m_panelPoints[m_panelPoints.Count - 1], r2, out intersection_b1, out intersection_b2); if (intersection_a1.X >= intersection_a2.X) { m_panelPoints.Add(intersection_a1); } else { m_panelPoints.Add(intersection_a2); } if (intersection_b1.X >= intersection_b2.X) { edge2.Add(intersection_b1); } else { edge2.Add(intersection_b2); } } for (int ii = 2; ii < chine1.Count; ii++) { // advance edge1 by one point r1 = (chine1[ii - 1] - chine1[ii]).Length; r2 = (chine2[ii - 1] - chine1[ii]).Length; GeometryOperations.Intersection(m_panelPoints[m_panelPoints.Count - 1], r1, edge2[edge2.Count - 1], r2, out intersection_a1, out intersection_a2); // advance edge2 by one point r1 = (chine2[ii - 1] - chine2[ii]).Length; r2 = (chine1[ii - 1] - chine2[ii]).Length; GeometryOperations.Intersection(edge2[edge2.Count - 1], r1, m_panelPoints[m_panelPoints.Count - 1], r2, out intersection_b1, out intersection_b2); Vector v_1 = m_panelPoints[m_panelPoints.Count - 1] - m_panelPoints[m_panelPoints.Count - 2]; Vector v_1a = intersection_a1 - m_panelPoints[m_panelPoints.Count - 1]; Vector v_1b = intersection_a2 - m_panelPoints[m_panelPoints.Count - 1]; Vector v_2 = edge2[edge2.Count - 1] - edge2[edge2.Count - 2]; Vector v_2a = intersection_b1 - edge2[edge2.Count - 1]; Vector v_2b = intersection_b2 - edge2[edge2.Count - 1]; double a1 = Math.Abs(Vector.AngleBetween(v_1, v_1a)); double a2 = Math.Abs(Vector.AngleBetween(v_1, v_1b)); double b1 = Math.Abs(Vector.AngleBetween(v_2, v_2a)); double b2 = Math.Abs(Vector.AngleBetween(v_2, v_2b)); if (a1 < a2) { m_panelPoints.Add(intersection_a1); } else { m_panelPoints.Add(intersection_a2); } if (b1 < b2) { edge2.Add(intersection_b1); } else { edge2.Add(intersection_b2); } } // NOTE: Should check for closed tail? for (int ii = edge2.Count - 1; ii >= 0; ii--) { m_panelPoints.Add(edge2[ii]); } }
protected void Panelize(Point3DCollection chine1, Point3DCollection chine2) { double r1, r2; Point intersection_a1, intersection_a2; Point intersection_b1, intersection_b2; PointCollection edge2 = new PointCollection(); m_panelPoints = new PointCollection(); bool pointy_bow = (chine1[0] - chine2[0]).Length < MIN_EDGE_LENGTH; bool pointy_stern = (chine1[chine1.Count - 1] - chine2[chine1.Count - 1]).Length < MIN_EDGE_LENGTH; if (pointy_bow) { m_panelPoints.Add(new Point(0, 0)); edge2.Add(new Point(0, 0)); r1 = (chine1[0] - chine1[1]).Length; m_panelPoints.Add(new Point(r1 * Math.Cos(Math.PI / 4), r1 * Math.Sin(Math.PI / 4))); } else { // Start at origin m_panelPoints.Add(new Point(0, 0)); edge2.Add(new Point(0, 0)); // Make the edge the first segment in edge2 r1 = (chine1[0] - chine2[0]).Length; edge2.Add(new Point(0, -r1)); // Compute next point, and favor positive X direction // advance edge1 by one point r1 = (chine1[0] - chine1[1]).Length; r2 = (chine2[0] - chine1[1]).Length; GeometryOperations.Intersection(m_panelPoints[m_panelPoints.Count - 1], r1, edge2[edge2.Count - 1], r2, out intersection_a1, out intersection_a2); if (intersection_a1.X >= intersection_a2.X) { m_panelPoints.Add(intersection_a1); } else { m_panelPoints.Add(intersection_a2); } } // Add next point to edge2 r1 = (chine2[0] - chine2[1]).Length; r2 = (chine1[1] - chine2[1]).Length; GeometryOperations.Intersection(edge2[edge2.Count - 1], r1, m_panelPoints[m_panelPoints.Count - 1], r2, out intersection_b1, out intersection_b2); if (intersection_b1.X >= intersection_b2.X) { edge2.Add(intersection_b1); } else { edge2.Add(intersection_b2); } // Complete the rest of the points int last_point; if (pointy_stern) { last_point = chine1.Count - 2; } else { last_point = chine1.Count - 1; } for (int ii = 1; ii < last_point; ii++) { r1 = (chine1[ii] - chine1[ii + 1]).Length; r2 = (chine2[ii] - chine1[ii + 1]).Length; GeometryOperations.Intersection(m_panelPoints[m_panelPoints.Count - 1], r1, edge2[edge2.Count - 1], r2, out intersection_a1, out intersection_a2); Vector v_1 = m_panelPoints[m_panelPoints.Count - 1] - m_panelPoints[m_panelPoints.Count - 2]; Vector v_1a = intersection_a1 - m_panelPoints[m_panelPoints.Count - 1]; Vector v_1b = intersection_a2 - m_panelPoints[m_panelPoints.Count - 1]; double a1 = Math.Abs(Vector.AngleBetween(v_1, v_1a)); double a2 = Math.Abs(Vector.AngleBetween(v_1, v_1b)); if (a1 < a2) { m_panelPoints.Add(intersection_a1); } else { m_panelPoints.Add(intersection_a2); } // advance edge2 by one point r1 = (chine2[ii] - chine2[ii + 1]).Length; r2 = (chine1[ii + 1] - chine2[ii + 1]).Length; GeometryOperations.Intersection(edge2[edge2.Count - 1], r1, m_panelPoints[m_panelPoints.Count - 1], r2, out intersection_b1, out intersection_b2); Vector v_2 = edge2[edge2.Count - 1] - edge2[edge2.Count - 2]; Vector v_2a = intersection_b1 - edge2[edge2.Count - 1]; Vector v_2b = intersection_b2 - edge2[edge2.Count - 1]; double b1 = Math.Abs(Vector.AngleBetween(v_2, v_2a)); double b2 = Math.Abs(Vector.AngleBetween(v_2, v_2b)); if (b1 < b2) { edge2.Add(intersection_b1); } else { edge2.Add(intersection_b2); } } if (pointy_stern) { r1 = (chine1[chine1.Count - 2] - chine1[chine1.Count - 1]).Length; r2 = (chine2[chine2.Count - 2] - chine2[chine2.Count - 1]).Length; GeometryOperations.Intersection(m_panelPoints[m_panelPoints.Count - 1], r1, edge2[edge2.Count - 1], r2, out intersection_a1, out intersection_a2); Vector v_1 = m_panelPoints[m_panelPoints.Count - 1] - m_panelPoints[m_panelPoints.Count - 2]; Vector v_1a = intersection_a1 - m_panelPoints[m_panelPoints.Count - 1]; Vector v_1b = intersection_a2 - m_panelPoints[m_panelPoints.Count - 1]; double a1 = Math.Abs(Vector.AngleBetween(v_1, v_1a)); double a2 = Math.Abs(Vector.AngleBetween(v_1, v_1b)); if (a1 < a2) { m_panelPoints.Add(intersection_a1); } else { m_panelPoints.Add(intersection_a2); } // Don't need to add point to edge2 because it is the same (pointy) point and it would be a duplicate } // Copy edge2 input m_panelPoints for (int ii = edge2.Count - 1; ii >= 0; ii--) { m_panelPoints.Add(edge2[ii]); } }