示例#1
0
        public static Polyline Extend(this Polyline curve, double start = 0.0, double end = 0.0, bool tangentExtensions = false, double tolerance = Tolerance.Distance)
        {
            if (curve.IsClosed(tolerance))
            {
                Reflection.Compute.RecordNote("Cannot Trim or Extend closed curves.");
                return(curve);
            }

            if (start + end + curve.Length() < tolerance)
            {
                Reflection.Compute.RecordError("Negative extend values are smaller than curve length.");
                return(null);
            }

            Polyline    result = new Polyline();
            List <Line> lines  = curve.SubParts();

            if (start < 0 && -start > lines[0].ILength())
            {
                double startCut = -lines[0].ILength();

                while (startCut > start && lines.Count > 1)
                {
                    lines.RemoveAt(0);
                    startCut -= lines[0].ILength();
                }

                startCut += lines[0].ILength();

                if (lines.Count > 1)
                {
                    lines[0] = lines[0].Extend(start - startCut, 0, false, tolerance);
                }
                else
                {
                    lines[0] = lines[0].Extend(start - startCut, end, tangentExtensions, tolerance);
                    result   = Create.Polyline(lines);
                    return(result);
                }
            }
            else
            {
                lines[0] = lines[0].Extend(start, 0, tangentExtensions, tolerance);
            }

            if (end < 0 && -end > lines[lines.Count - 1].ILength())
            {
                double endCut = -lines[lines.Count - 1].ILength();
                while (endCut > end)
                {
                    lines.RemoveAt(lines.Count - 1);
                    endCut -= lines[lines.Count - 1].ILength();
                }
                endCut += lines[lines.Count - 1].ILength();
                lines[lines.Count - 1] = lines[lines.Count - 1].Extend(0, end - endCut, tangentExtensions, tolerance);
            }
            else
            {
                lines[lines.Count - 1] = lines[lines.Count - 1].Extend(0, end, tangentExtensions, tolerance);
            }

            result = Create.Polyline(lines);
            return(result);
        }
示例#2
0
        /***************************************************/

        public static bool IsContaining(this Polyline curve, List <Point> points, bool acceptOnEdge = true, double tolerance = Tolerance.Distance)
        {
            // Todo:
            // check boundingBox/proximity at the beginning!
            // project to 2D & rewrite methods to 2D to improve performance
            // - to be replaced with a general method for a nurbs curve?
            // - could be done with a ray instead of an infinite line!

            if (curve.IsClosed(tolerance))
            {
                Plane  p     = curve.FitPlane(tolerance);
                double sqTol = tolerance * tolerance;

                if (p == null)
                {
                    if (acceptOnEdge)
                    {
                        foreach (Point pt in points)
                        {
                            if (curve.ClosestPoint(pt).SquareDistance(pt) > sqTol)
                            {
                                return(false);
                            }
                        }
                        return(true);
                    }
                    else
                    {
                        return(false);
                    }
                }
                else
                {
                    List <Line>   subParts       = curve.SubParts();
                    List <Vector> edgeDirections = subParts.Select(c => c.Direction()).ToList();
                    foreach (Point pt in points)
                    {
                        Point pPt = pt.Project(p);
                        if (pPt.SquareDistance(pt) <= sqTol)
                        {
                            Point  end       = p.Origin;
                            Vector direction = (end - pPt).Normalise();
                            while (direction.SquareLength() <= 0.5 || edgeDirections.Any(e => 1 - Math.Abs(e.DotProduct(direction)) <= Tolerance.Angle))
                            {
                                end       = end.Translate(Create.RandomVectorInPlane(p, true));
                                direction = (end - pPt).Normalise();
                            }

                            Line ray = new Line {
                                Start = pPt, End = end
                            };
                            ray.Infinite = true;
                            List <Point> intersects      = new List <Point>();
                            List <Point> extraIntersects = new List <Point>();

                            Func <double, double, double> ToFactor = (t, n) => (1 - t * t) / (1 - n * n);

                            Line   current       = subParts[1];
                            double prevTolFactor = ToFactor(subParts[0].Direction().DotProduct(direction), current.Direction().DotProduct(direction));

                            for (int i = 1; i < subParts.Count + 1; i++)
                            {
                                Line next = subParts[(i + 1) % subParts.Count];

                                double nextTolFactor = ToFactor(next.Direction().DotProduct(direction), current.Direction().DotProduct(direction));

                                Point iPt = current.LineIntersection(ray, false, tolerance);
                                if (iPt != null)
                                {
                                    double signedAngle = direction.SignedAngle(current.Direction(), p.Normal);
                                    if ((current.Start.SquareDistance(iPt) <= sqTol * prevTolFactor)) // Will we get a point on the previous line
                                    {
                                        if (signedAngle > Tolerance.Angle)
                                        {
                                            intersects.Add(iPt);
                                        }
                                        else
                                        {
                                            extraIntersects.Add(iPt);
                                        }
                                    }
                                    else if ((current.End.SquareDistance(iPt) <= sqTol * nextTolFactor))  // Will we get a point on the next line
                                    {
                                        if (signedAngle < -Tolerance.Angle)
                                        {
                                            intersects.Add(iPt);
                                        }
                                        else
                                        {
                                            extraIntersects.Add(iPt);
                                        }
                                    }
                                    else
                                    {
                                        intersects.Add(iPt);
                                    }
                                }
                                prevTolFactor = 1 / nextTolFactor;
                                current       = next;
                            }

                            if (intersects.Count == 0)
                            {
                                return(false);
                            }

                            if ((pPt.ClosestPoint(intersects.Union(extraIntersects)).SquareDistance(pPt) <= sqTol))
                            {
                                if (acceptOnEdge)
                                {
                                    continue;
                                }
                                else
                                {
                                    return(false);
                                }
                            }

                            intersects.Add(pPt);
                            intersects = intersects.SortCollinear(tolerance);
                            for (int j = 0; j < intersects.Count; j++)
                            {
                                if (j % 2 == 0 && intersects[j] == pPt)
                                {
                                    return(false);
                                }
                            }
                        }
                        else
                        {
                            return(false);
                        }
                    }
                    return(true);
                }
            }
            return(false);
        }
示例#3
0
        /***************************************************/

        public static Cartesian Mirror(this Cartesian coordinateSystem, Plane p)
        {
            return(Create.CartesianCoordinateSystem(coordinateSystem.Origin.Mirror(p), coordinateSystem.X.Mirror(p), coordinateSystem.Y.Mirror(p)));
        }
示例#4
0
        /***************************************************/

        public static ICurve Project(this Ellipse ellipse, Plane p)
        {
            TransformMatrix project = Create.ProjectionMatrix(p, p.Normal);

            return(ellipse.Transform(project));
        }
示例#5
0
        /***************************************************/

        public static List <IntegrationSlice> IntegrationSlices(List <ICurve> edges, Vector direction, double increment = 0.001, double tolerance = Tolerance.Distance)
        {
            List <IntegrationSlice> slices = new List <IntegrationSlice>();

            if (edges.Count == 0)
            {
                return(slices);
            }

            List <double> cutAt         = new List <double>();
            List <double> sliceSegments = new List <double>();
            Plane         p             = new Plane {
                Origin = oM.Geometry.Point.Origin, Normal = direction
            };

            for (int i = 0; i < edges.Count; i++)
            {
                for (int j = 0; j < edges[i].IControlPoints().Count; j++)
                {
                    cutAt.Add(Query.DotProduct(Create.Vector(edges[i].IControlPoints()[j]), p.Normal));
                }
            }

            cutAt.Sort();
            cutAt = cutAt.Distinct <double>().ToList();

            double currentValue = Query.DotProduct(Create.Vector(Query.Bounds(new PolyCurve {
                Curves = edges
            }).Min), p.Normal);
            double max = Query.DotProduct(Create.Vector(Query.Bounds(new PolyCurve {
                Curves = edges
            }).Max), p.Normal);
            int index = 0;

            while (currentValue < max)
            {
                if (cutAt.Count > index && currentValue > cutAt[index])
                {
                    sliceSegments.Add(cutAt[index]);
                    index++;
                }
                else
                {
                    sliceSegments.Add(currentValue);
                    currentValue += increment;
                }
            }

            sliceSegments.Add(max);

            for (int i = 0; i < sliceSegments.Count - 1; i++)
            {
                if (sliceSegments[i] == sliceSegments[i + 1])
                {
                    continue;
                }

                currentValue = (sliceSegments[i] + sliceSegments[i + 1]) / 2;
                slices.Add(Query.SliceAt(edges, currentValue, -sliceSegments[i] + sliceSegments[i + 1], p, tolerance));
            }

            return(slices);
        }
示例#6
0
        public static T Orient <T>(this T geometry, Cartesian csFrom, Cartesian csTo) where T : IGeometry
        {
            TransformMatrix orientationMatrix = Create.OrientationMatrix(csFrom, csTo);

            return((T)ITransform(geometry, orientationMatrix));
        }
示例#7
0
        /***************************************************/

        public static bool IsContaining(this Polyline curve, List <Point> points, bool acceptOnEdge = true, double tolerance = Tolerance.Distance)
        {
            // Todo:
            // check boundingBox/proximity at the beginning!
            // project to 2D & rewrite methods to 2D to improve performance
            // - to be replaced with a general method for a nurbs curve?
            // - could be done with a ray instead of an infinite line!

            if (curve.IsClosed(tolerance))
            {
                Plane  p     = curve.FitPlane(tolerance);
                double sqTol = tolerance * tolerance;

                if (p == null)
                {
                    if (acceptOnEdge)
                    {
                        foreach (Point pt in points)
                        {
                            if (curve.ClosestPoint(pt).SquareDistance(pt) > sqTol)
                            {
                                return(false);
                            }
                        }
                        return(true);
                    }
                    else
                    {
                        return(false);
                    }
                }

                else
                {
                    foreach (Point pt in points)
                    {
                        Point pPt = pt.Project(p);
                        if (pPt.SquareDistance(pt) <= sqTol)
                        {
                            Point end = p.Origin;
                            if (pPt.SquareDistance(end) <= sqTol)
                            {
                                end = end.Translate(Create.RandomVectorInPlane(p, true));
                            }

                            Line ray = new Line {
                                Start = pPt, End = end
                            };
                            ray.Infinite = true;
                            Vector       rayDir          = ray.Direction();
                            List <Line>  subParts        = curve.SubParts();
                            List <Point> intersects      = new List <Point>();
                            List <Point> extraIntersects = new List <Point>();

                            foreach (Line subPart in subParts)
                            {
                                Point iPt = subPart.LineIntersection(ray, false, tolerance);
                                if (iPt != null)
                                {
                                    double signedAngle = rayDir.SignedAngle(subPart.Direction(), p.Normal);
                                    if ((subPart.Start.SquareDistance(iPt) <= sqTol))
                                    {
                                        if (signedAngle > Tolerance.Angle)
                                        {
                                            intersects.Add(iPt);
                                        }
                                        else
                                        {
                                            extraIntersects.Add(iPt);
                                        }
                                    }
                                    else if ((subPart.End.SquareDistance(iPt) <= sqTol))
                                    {
                                        if (signedAngle < -Tolerance.Angle)
                                        {
                                            intersects.Add(iPt);
                                        }
                                        else
                                        {
                                            extraIntersects.Add(iPt);
                                        }
                                    }
                                    else
                                    {
                                        intersects.Add(iPt);
                                    }
                                }
                            }

                            if (intersects.Count == 0)
                            {
                                return(false);
                            }
                            if ((pPt.ClosestPoint(intersects.Union(extraIntersects)).SquareDistance(pPt) <= sqTol))
                            {
                                if (acceptOnEdge)
                                {
                                    continue;
                                }
                                else
                                {
                                    return(false);
                                }
                            }

                            intersects.Add(pPt);
                            intersects = intersects.SortCollinear(tolerance);
                            for (int j = 0; j < intersects.Count; j++)
                            {
                                if (j % 2 == 0 && intersects[j] == pPt)
                                {
                                    return(false);
                                }
                            }
                        }
                        else
                        {
                            return(false);
                        }
                    }
                    return(true);
                }
            }
            return(false);
        }
示例#8
0
        /***************************************************/
        /**** Public Methods - Others                   ****/
        /***************************************************/

        public static Mesh Rotate(this Mesh mesh, Point origin, Vector axis, double rad)
        {
            TransformMatrix rotationMatrix = Create.RotationMatrix(origin, axis, rad);

            return(Transform(mesh, rotationMatrix));
        }
示例#9
0
        /***************************************************/

        public static ICurve Rotate(this Ellipse curve, Point origin, Vector axis, double rad)
        {
            TransformMatrix rotationMatrix = Create.RotationMatrix(origin, axis, rad);

            return(Transform(curve, rotationMatrix));
        }
示例#10
0
        /***************************************************/

        public static NurbsCurve ToNurbsCurve(this Line line)
        {
            return(Create.NurbsCurve(new List <Point> {
                line.Start, line.End
            }, new double[] { 1, 1 }, new double[] { 0, 1 }));
        }
示例#11
0
        /***************************************************/

        public static Basis Rotate(this Basis basis, double rad, Vector axis)
        {
            return(Create.Basis(basis.X.Rotate(rad, axis), basis.Y.Rotate(rad, axis)));
        }
示例#12
0
        /***************************************************/

        public static Plane Rotate(this Plane plane, Point origin, Vector axis, double rad)
        {
            TransformMatrix rotationMatrix = Create.RotationMatrix(origin, axis, rad);

            return(Transform(plane, rotationMatrix));
        }
示例#13
0
        /***************************************************/

        public static CompositeGeometry Rotate(this CompositeGeometry group, Point origin, Vector axis, double rad)
        {
            TransformMatrix rotationMatrix = Create.RotationMatrix(origin, axis, rad);

            return(Transform(group, rotationMatrix));
        }
示例#14
0
        /***************************************************/

        public static bool IsContaining(this PolyCurve curve, List <Point> points, bool acceptOnEdge = true, double tolerance = Tolerance.Distance)
        {
            // Todo:
            // - to be replaced with a general method for a nurbs curve?
            // - this is very problematic for edge cases (cutting line going through a sharp corner, to be superseded?

            BoundingBox box = curve.Bounds();

            if (points.Any(x => !box.IsContaining(x, true, tolerance)))
            {
                return(false);
            }

            if (!curve.IsClosed(tolerance))
            {
                return(false);
            }

            if (curve.Curves.Count == 1 && curve.Curves[0] is Circle)
            {
                return(IsContaining(curve.Curves[0] as Circle, points, acceptOnEdge, tolerance));
            }

            Plane  p     = curve.FitPlane(tolerance);
            double sqTol = tolerance * tolerance;

            if (p == null)
            {
                if (acceptOnEdge)
                {
                    foreach (Point pt in points)
                    {
                        if (curve.ClosestPoint(pt).SquareDistance(pt) > sqTol)
                        {
                            return(false);
                        }
                    }
                    return(true);
                }
                else
                {
                    return(false);
                }
            }

            List <ICurve> subParts       = curve.SubParts();
            List <Vector> edgeDirections = subParts.Where(s => s is Line).Select(c => (c as Line).Direction()).ToList();

            foreach (Point pt in points)
            {
                Point pPt = pt.Project(p);
                if (pPt.SquareDistance(pt) > sqTol) // not on the same plane
                {
                    return(false);
                }

                Point  end       = p.Origin;                                                                                                 // Avrage of control points
                Vector direction = (end - pPt).Normalise();                                                                                  // Gets a line cutting through the curves and the point
                while (direction.SquareLength() <= 0.5 || edgeDirections.Any(e => 1 - Math.Abs(e.DotProduct(direction)) <= Tolerance.Angle)) // not zeroa or parallel to edges
                {
                    end       = end.Translate(Create.RandomVectorInPlane(p, true));
                    direction = (end - pPt).Normalise();
                }

                Line ray = new Line {
                    Start = pPt, End = end
                };
                ray.Infinite = true;
                List <Point> intersects      = new List <Point>();
                List <Point> extraIntersects = new List <Point>();

                foreach (ICurve subPart in subParts)
                {
                    List <Point> iPts = subPart.ILineIntersections(ray, false, tolerance);   // LineIntersection ignores the `false`
                    foreach (Point iPt in iPts)
                    {
                        double signedAngle = direction.SignedAngle(subPart.ITangentAtPoint(iPt, tolerance), p.Normal);
                        if ((subPart.IStartPoint().SquareDistance(iPt) <= sqTol)) // Keep intersections from beeing counted twice?
                        {
                            if (signedAngle >= -Tolerance.Angle)                  // tangent is to the left of the direction
                            {
                                intersects.Add(iPt);
                            }
                            else
                            {
                                extraIntersects.Add(iPt);
                            }
                        }
                        else if ((subPart.IEndPoint().SquareDistance(iPt) <= sqTol))
                        {
                            if (signedAngle <= Tolerance.Angle)     // tangent is to the rigth of the direction
                            {
                                intersects.Add(iPt);
                            }
                            else
                            {
                                extraIntersects.Add(iPt);
                            }
                        }
                        else if (Math.Abs(signedAngle) <= Tolerance.Angle)  // They are parallel
                        {
                            extraIntersects.Add(iPt);
                        }
                        else
                        {
                            intersects.Add(iPt);
                        }
                    }
                }

                if (intersects.Count == 0)  // did not intersect the curve (strange)
                {
                    return(false);
                }

                if ((pPt.ClosestPoint(intersects.Union(extraIntersects)).SquareDistance(pPt) <= sqTol)) // if any intersection point is the point
                {
                    if (acceptOnEdge)
                    {
                        continue;
                    }
                    else
                    {
                        return(false);
                    }
                }

                intersects.Add(pPt);
                intersects = intersects.SortCollinear(tolerance);
                for (int j = 0; j < intersects.Count; j++)  // Even indecies on a colinerar sort is outside the region
                {
                    if (j % 2 == 0 && intersects[j] == pPt)
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
示例#15
0
        /***************************************************/

        public static bool IsContaining(this PolyCurve curve, List <Point> points, bool acceptOnEdge = true, double tolerance = Tolerance.Distance)
        {
            // Todo:
            // - to be replaced with a general method for a nurbs curve?
            // - this is very problematic for edge cases (cutting line going through a sharp corner, to be superseded?

            if (curve.IsClosed(tolerance))
            {
                Plane  p     = curve.FitPlane(tolerance);
                double sqTol = tolerance * tolerance;

                if (p == null)
                {
                    if (acceptOnEdge)
                    {
                        foreach (Point pt in points)
                        {
                            if (curve.ClosestPoint(pt).SquareDistance(pt) > sqTol)
                            {
                                return(false);
                            }
                        }
                        return(true);
                    }
                    else
                    {
                        return(false);
                    }
                }

                else
                {
                    foreach (Point pt in points)
                    {
                        Point pPt = pt.Project(p);
                        if (pPt.SquareDistance(pt) <= sqTol)
                        {
                            Point end = p.Origin;
                            if (pPt.SquareDistance(end) <= sqTol)
                            {
                                end = end.Translate(Create.RandomVectorInPlane(p, true));
                            }

                            Line ray = new Line {
                                Start = pPt, End = end
                            };
                            ray.Infinite = true;
                            Vector        rayDir          = ray.Direction();
                            List <ICurve> subParts        = curve.SubParts();
                            List <Point>  intersects      = new List <Point>();
                            List <Point>  extraIntersects = new List <Point>();

                            foreach (ICurve subPart in subParts)
                            {
                                List <Point> iPts = subPart.ILineIntersections(ray, false, tolerance);
                                foreach (Point iPt in iPts)
                                {
                                    double signedAngle = rayDir.SignedAngle(subPart.ITangentAtPoint(iPt, tolerance), p.Normal);
                                    if ((subPart.IStartPoint().SquareDistance(iPt) <= sqTol))
                                    {
                                        if (signedAngle >= -Tolerance.Angle)
                                        {
                                            intersects.Add(iPt);
                                        }
                                        else
                                        {
                                            extraIntersects.Add(iPt);
                                        }
                                    }
                                    else if ((subPart.IEndPoint().SquareDistance(iPt) <= sqTol))
                                    {
                                        if (signedAngle <= Tolerance.Angle)
                                        {
                                            intersects.Add(iPt);
                                        }
                                        else
                                        {
                                            extraIntersects.Add(iPt);
                                        }
                                    }
                                    else if (Math.Abs(signedAngle) <= Tolerance.Angle)
                                    {
                                        extraIntersects.Add(iPt);
                                    }
                                    else
                                    {
                                        intersects.Add(iPt);
                                    }
                                }
                            }

                            if (intersects.Count == 0)
                            {
                                return(false);
                            }
                            if ((pPt.ClosestPoint(intersects.Union(extraIntersects)).SquareDistance(pPt) <= sqTol))
                            {
                                if (acceptOnEdge)
                                {
                                    continue;
                                }
                                else
                                {
                                    return(false);
                                }
                            }

                            intersects.Add(pPt);
                            intersects = intersects.SortCollinear(tolerance);
                            for (int j = 0; j < intersects.Count; j++)
                            {
                                if (j % 2 == 0 && intersects[j] == pPt)
                                {
                                    return(false);
                                }
                            }
                        }
                        else
                        {
                            return(false);
                        }
                    }
                    return(true);
                }
            }
            return(false);
        }
示例#16
0
        /***************************************************/

        private static PolyCurve Fillet(this ICurve curve1, ICurve curve2, bool tangentExtensions, bool keepCurve1StartPoint, bool keepCurve2StartPoint, double tolerance = Tolerance.Distance)
        {
            //TODO:
            //Write a proper fillet method, test and make it public

            if (!((curve1 is Line || curve1 is Arc) && (curve2 is Line || curve2 is Arc))) //for now works only with combinations of lines and arcs
            {
                Reflection.Compute.RecordError("Private method fillet is implemented only for PolyCurves consisting of Lines or Arcs.");
                return(null);
            }

            List <PolyCurve> joinCurves = Compute.IJoin(new List <ICurve> {
                curve1, curve2
            }, tolerance).ToList();

            if (joinCurves.Count == 1)
            {
                return(joinCurves[0]);
            }

            List <ICurve> resultCurves = new List <ICurve>();

            bool C1SP = keepCurve1StartPoint;
            bool C2SP = keepCurve2StartPoint;

            List <Point> intersections = curve1.ICurveIntersections(curve2, tolerance);

            if (intersections.Count > 2)
            {
                Reflection.Compute.RecordError("Invalid number of intersections between curves. Two lines/arcs can have no more than two intersections.");
            }
            else if (intersections.Count == 2 || intersections.Count == 1)
            {
                Point intersection = intersections[0];
                if (intersections.Count == 2)
                {
                    double maxdist = double.MaxValue;
                    if (C1SP)
                    {
                        foreach (Point p in intersections)
                        {
                            double dist = p.SquareDistance(curve1.IStartPoint());
                            if (dist < maxdist)
                            {
                                intersection = p;
                                maxdist      = dist;
                            }
                        }
                    }
                    else
                    {
                        foreach (Point p in intersections)
                        {
                            double dist = p.SquareDistance(curve1.IEndPoint());
                            if (dist < maxdist)
                            {
                                intersection = p;
                                maxdist      = dist;
                            }
                        }
                    }
                }
                else
                {
                    intersection = intersections[0];
                }

                if (C1SP && C2SP)
                {
                    resultCurves.AddRange(curve1.ExtendToPoint(curve1.IStartPoint(), intersection, tangentExtensions, tolerance));
                    resultCurves.AddRange(curve2.ExtendToPoint(curve2.IStartPoint(), intersection, tangentExtensions, tolerance));
                    resultCurves[1] = resultCurves[1].IFlip();
                }
                else if (C1SP && !C2SP)
                {
                    resultCurves.AddRange(curve1.ExtendToPoint(curve1.IStartPoint(), intersection, tangentExtensions, tolerance));
                    resultCurves.AddRange(curve2.ExtendToPoint(intersection, curve2.IEndPoint(), tangentExtensions, tolerance));
                }
                else if (!C1SP && C2SP)
                {
                    resultCurves.AddRange(curve1.ExtendToPoint(intersection, curve1.IEndPoint(), tangentExtensions, tolerance));
                    resultCurves.AddRange(curve2.ExtendToPoint(curve2.IStartPoint(), intersection, tangentExtensions, tolerance));
                    resultCurves[0] = resultCurves[0].IFlip();
                    resultCurves[1] = resultCurves[1].IFlip();
                }
                else
                {
                    resultCurves.AddRange(curve1.ExtendToPoint(intersection, curve1.IEndPoint(), tangentExtensions, tolerance));
                    resultCurves.AddRange(curve2.ExtendToPoint(intersection, curve2.IEndPoint(), tangentExtensions, tolerance));
                    resultCurves[0] = resultCurves[0].IFlip();
                }
            }
            else
            {
                if (curve1 is Line && curve2 is Line)
                {
                    Point intersection = (curve1 as Line).LineIntersection(curve2 as Line, true, tolerance);
                    if (C1SP && C2SP)
                    {
                        if ((curve1.IStartPoint().Distance((curve2 as Line), true) < curve1.IEndPoint().Distance((curve2 as Line), true) &&
                             !intersection.IIsOnCurve(curve1)) ||
                            (curve2.IStartPoint().Distance((curve1 as Line), true) < curve2.IEndPoint().Distance((curve1 as Line), true) &&
                             !intersection.IIsOnCurve(curve2)))
                        {
                            Reflection.Compute.RecordWarning("Couldn't provide correct fillet for given input");
                            return(null);
                        }
                        resultCurves.AddRange(curve1.ExtendToPoint(curve1.IStartPoint(), intersection, tangentExtensions, tolerance));
                        resultCurves.AddRange(curve2.ExtendToPoint(curve2.IStartPoint(), intersection, tangentExtensions, tolerance));
                        resultCurves[1] = resultCurves[1].IFlip();
                    }
                    else if (C1SP && !C2SP)
                    {
                        if ((curve1.IStartPoint().Distance((curve2 as Line), true) < curve1.IEndPoint().Distance((curve2 as Line), true) &&
                             !intersection.IIsOnCurve(curve1)) ||
                            (curve2.IStartPoint().Distance((curve1 as Line), true) > curve2.IEndPoint().Distance((curve1 as Line), true) &&
                             !intersection.IIsOnCurve(curve2)))
                        {
                            Reflection.Compute.RecordWarning("Couldn't provide correct fillet for given input");
                            return(null);
                        }
                        resultCurves.AddRange(curve1.ExtendToPoint(curve1.IStartPoint(), intersection, tangentExtensions, tolerance));
                        resultCurves.AddRange(curve2.ExtendToPoint(intersection, curve2.IEndPoint(), tangentExtensions, tolerance));
                    }
                    else if (!C1SP && C2SP)
                    {
                        if ((curve1.IStartPoint().Distance((curve2 as Line), true) > curve1.IEndPoint().Distance((curve2 as Line), true) &&
                             !intersection.IIsOnCurve(curve1)) ||
                            (curve2.IStartPoint().Distance((curve1 as Line), true) < curve2.IEndPoint().Distance((curve1 as Line), true) &&
                             !intersection.IIsOnCurve(curve2)))
                        {
                            Reflection.Compute.RecordWarning("Couldn't provide correct fillet for given input");
                            return(null);
                        }
                        resultCurves.AddRange(curve1.ExtendToPoint(intersection, curve1.IEndPoint(), tangentExtensions, tolerance));
                        resultCurves.AddRange(curve2.ExtendToPoint(curve2.IStartPoint(), intersection, tangentExtensions, tolerance));
                        resultCurves[0] = resultCurves[0].IFlip();
                        resultCurves[1] = resultCurves[1].IFlip();
                    }
                    else
                    {
                        if ((curve1.IStartPoint().Distance((curve2 as Line), true) > curve1.IEndPoint().Distance((curve2 as Line), true) &&
                             !intersection.IIsOnCurve(curve1)) ||
                            (curve2.IStartPoint().Distance((curve1 as Line), true) > curve2.IEndPoint().Distance((curve1 as Line), true) &&
                             !intersection.IIsOnCurve(curve2)))
                        {
                            Reflection.Compute.RecordWarning("Couldn't provide correct fillet for given input");
                            return(null);
                        }
                        resultCurves.AddRange(curve1.ExtendToPoint(intersection, curve1.IEndPoint(), tangentExtensions, tolerance));
                        resultCurves.AddRange(curve2.ExtendToPoint(intersection, curve2.IEndPoint(), tangentExtensions, tolerance));
                        resultCurves[0] = resultCurves[0].IFlip();
                    }
                }
                else
                {
                    Point intersection;
                    if (!tangentExtensions)
                    {
                        PolyCurve pCurve1 = new PolyCurve();
                        PolyCurve pCurve2 = new PolyCurve();
                        if (curve1 is Arc)
                        {
                            pCurve1.Curves.Add(new Circle {
                                Centre = (curve1 as Arc).Centre(), Normal = (curve1 as Arc).Normal(), Radius = (curve1 as Arc).Radius
                            });
                        }
                        else
                        {
                            pCurve1.Curves.Add(new Line {
                                Start = (curve1 as Line).Start, End = (curve1 as Line).End, Infinite = true
                            });
                        }

                        if (curve2 is Arc)
                        {
                            pCurve2.Curves.Add(new Circle {
                                Centre = (curve2 as Arc).Centre(), Normal = (curve2 as Arc).Normal(), Radius = (curve2 as Arc).Radius
                            });
                        }
                        else
                        {
                            pCurve2.Curves.Add(new Line {
                                Start = (curve2 as Line).Start, End = (curve2 as Line).End, Infinite = true
                            });
                        }

                        List <Point> curveIntersections = pCurve1.CurveIntersections(pCurve2, tolerance);
                        if (curveIntersections.Count == 0)
                        {
                            Reflection.Compute.RecordError("Curves' extensions do not intersect");
                            return(null);
                        }
                        if (C1SP && C2SP)
                        {
                            intersection = curveIntersections.ClosestPoint(curve1.IEndPoint());

                            resultCurves.AddRange(curve1.ExtendToPoint(curve1.IStartPoint(), intersection, tangentExtensions, tolerance));
                            resultCurves.AddRange(curve2.ExtendToPoint(curve2.IStartPoint(), intersection, tangentExtensions, tolerance));
                            resultCurves[1] = resultCurves[1].IFlip();
                        }
                        else if (C1SP && !C2SP)
                        {
                            intersection = curveIntersections.ClosestPoint(curve1.IEndPoint());
                            resultCurves.AddRange(curve1.ExtendToPoint(curve1.IStartPoint(), intersection, tangentExtensions, tolerance));
                            resultCurves.AddRange(curve2.ExtendToPoint(intersection, curve2.IEndPoint(), tangentExtensions, tolerance));
                        }
                        else if (!C1SP && C2SP)
                        {
                            intersection = curveIntersections.ClosestPoint(curve1.IStartPoint());
                            resultCurves.AddRange(curve1.ExtendToPoint(intersection, curve1.IEndPoint(), tangentExtensions, tolerance));
                            resultCurves.AddRange(curve2.ExtendToPoint(curve2.IStartPoint(), intersection, tangentExtensions, tolerance));
                            resultCurves[0] = resultCurves[0].IFlip();
                            resultCurves[1] = resultCurves[1].IFlip();
                        }
                        else
                        {
                            intersection = curveIntersections.ClosestPoint(curve1.IStartPoint());
                            resultCurves.AddRange(curve1.ExtendToPoint(intersection, curve1.IEndPoint(), tangentExtensions, tolerance));
                            resultCurves.AddRange(curve2.ExtendToPoint(intersection, curve2.IEndPoint(), tangentExtensions, tolerance));
                            resultCurves[0] = resultCurves[0].IFlip();
                        }
                    }
                    else
                    {
                        if (C1SP && C2SP)
                        {
                            Line tanLine1 = Create.Line(curve1.IEndPoint(), curve1.IEndDir() / tolerance);
                            tanLine1.Infinite = false;
                            PolyCurve pCurve1 = new PolyCurve {
                                Curves = { curve1, tanLine1 }
                            };

                            Line tanLine2 = Create.Line(curve2.IEndPoint(), curve2.IEndDir() / tolerance);
                            tanLine2.Infinite = false;
                            PolyCurve pCurve2 = new PolyCurve {
                                Curves = { curve2, tanLine2 }
                            };

                            List <Point> curveIntersecions = pCurve1.CurveIntersections(pCurve2, tolerance);
                            if (curveIntersecions.Count > 0)
                            {
                                intersection = curveIntersecions.ClosestPoint(curve1.IEndPoint());
                            }
                            else
                            {
                                Reflection.Compute.RecordWarning("Couldn't create fillet");
                                return(null);
                            }

                            PolyCurve subResult1 = new PolyCurve
                            {
                                Curves = curve1.ExtendToPoint(curve1.IStartPoint(), intersection, tangentExtensions, tolerance).ToList()
                            };

                            PolyCurve subResult2 = new PolyCurve
                            {
                                Curves = curve2.ExtendToPoint(curve2.IStartPoint(), intersection, tangentExtensions, tolerance).ToList()
                            };

                            subResult2 = subResult2.Flip();

                            resultCurves.AddRange(subResult1.Curves);
                            resultCurves.AddRange(subResult2.Curves);
                        }
                        else if (C1SP && !C2SP)
                        {
                            Line tanLine1 = Create.Line(curve1.IEndPoint(), curve1.IEndDir() / tolerance);
                            tanLine1.Infinite = false;
                            PolyCurve pCurve1 = new PolyCurve {
                                Curves = { curve1, tanLine1 }
                            };

                            Line tanLine2 = Create.Line(curve2.IStartPoint(), curve2.IStartDir().Reverse() / tolerance);
                            tanLine2.Infinite = false;
                            PolyCurve pCurve2 = new PolyCurve {
                                Curves = { tanLine2, curve2 }
                            };

                            List <Point> curveIntersecions = pCurve1.ICurveIntersections(pCurve2, tolerance);

                            if (curveIntersecions.Count > 0)
                            {
                                intersection = curveIntersecions.ClosestPoint(curve1.IEndPoint());
                            }
                            else
                            {
                                Reflection.Compute.RecordWarning("Couldn't create fillet");
                                return(null);
                            }

                            resultCurves.AddRange(curve1.ExtendToPoint(curve1.IStartPoint(), intersection, tangentExtensions, tolerance));
                            resultCurves.AddRange(curve2.ExtendToPoint(intersection, curve2.IEndPoint(), tangentExtensions, tolerance));
                        }
                        else if (!C1SP && C2SP)
                        {
                            Line tanLine1 = Create.Line(curve1.IStartPoint(), curve1.IStartDir().Reverse() / tolerance);
                            tanLine1.Infinite = false;
                            PolyCurve pCurve1 = new PolyCurve {
                                Curves = { tanLine1, curve1 }
                            };

                            Line tanLine2 = Create.Line(curve2.IEndPoint(), curve2.IEndDir() / tolerance);
                            tanLine2.Infinite = false;
                            PolyCurve pCurve2 = new PolyCurve {
                                Curves = { curve2, tanLine2 }
                            };

                            List <Point> curveIntersecions = pCurve1.ICurveIntersections(pCurve2, tolerance);
                            if (curveIntersecions.Count > 0)
                            {
                                intersection = curveIntersecions.ClosestPoint(curve1.IStartPoint());
                            }
                            else
                            {
                                Reflection.Compute.RecordWarning("Couldn't create fillet");
                                return(null);
                            }
                            PolyCurve subResult1 = new PolyCurve
                            {
                                Curves = curve1.ExtendToPoint(intersection, curve1.IEndPoint(), tangentExtensions, tolerance).ToList()
                            };
                            PolyCurve subResult2 = new PolyCurve
                            {
                                Curves = curve2.ExtendToPoint(curve2.IStartPoint(), intersection, tangentExtensions, tolerance).ToList()
                            };

                            subResult1 = subResult1.Flip();
                            subResult2 = subResult2.Flip();

                            resultCurves.AddRange(subResult1.Curves);
                            resultCurves.AddRange(subResult2.Curves);
                        }
                        else
                        {
                            Line tanLine1 = Create.Line(curve1.IStartPoint(), curve1.IStartDir().Reverse() / tolerance);
                            tanLine1.Infinite = false;
                            PolyCurve pCurve1 = new PolyCurve {
                                Curves = { tanLine1, curve1 }
                            };

                            Line tanLine2 = Create.Line(curve2.IStartPoint(), curve2.IStartDir().Reverse() / tolerance);
                            tanLine2.Infinite = false;
                            PolyCurve pCurve2 = new PolyCurve {
                                Curves = { tanLine2, curve2 }
                            };

                            List <Point> curveIntersecions = pCurve1.ICurveIntersections(pCurve2, tolerance);
                            if (curveIntersecions.Count > 0)
                            {
                                intersection = curveIntersecions.ClosestPoint(curve1.IStartPoint());
                            }
                            else
                            {
                                Reflection.Compute.RecordWarning("Couldn't create fillet");
                                return(null);
                            }
                            PolyCurve subResult1 = new PolyCurve
                            {
                                Curves = curve1.ExtendToPoint(intersection, curve1.IEndPoint(), tangentExtensions, tolerance).ToList()
                            };
                            PolyCurve subResult2 = new PolyCurve
                            {
                                Curves = curve2.ExtendToPoint(intersection, curve2.IEndPoint(), tangentExtensions, tolerance).ToList()
                            };

                            subResult1 = subResult1.Flip();

                            resultCurves.AddRange(subResult1.Curves);
                            resultCurves.AddRange(subResult2.Curves);
                        }
                    }
                }
            }

            for (int i = resultCurves.Count - 1; i >= 0; i--)
            {
                if (resultCurves[i] is PolyCurve)
                {
                    PolyCurve temp = (PolyCurve)resultCurves[i];
                    resultCurves.RemoveAt(i);
                    resultCurves.InsertRange(i, temp.Curves);
                }
            }

            PolyCurve result = new PolyCurve {
                Curves = resultCurves
            };

            return(result);
        }
示例#17
0
        /***************************************************/

        public static PolySurface Rotate(this PolySurface surface, Point origin, Vector axis, double rad)
        {
            TransformMatrix rotationMatrix = Create.RotationMatrix(origin, axis, rad);

            return(Transform(surface, rotationMatrix));
        }