Ejemplo n.º 1
0
        public void ShouldCheckNotIntersectWithOtherLine()
        {
            var line2D = new Line2d(new Point(2, 3), new Point(4, 5));
            var other = new Line2d(new Point(2, 4), new Point(4, 6));

            Assert.IsFalse(line2D.HasIntersectWith(other));
        }
Ejemplo n.º 2
0
        public void Split_GivenNonIntersectingLine2_ShouldReturnNull()
        {
            // Arrange.
            var v1         = new Point2d(20, 20);
            var v2         = new Point2d(20, -20);
            var testObject = new Line2d(v1, v2);

            v1 = new Point2d(-10, 0);
            v2 = new Point2d(10, 0);
            var nonIntersectingLine = new Line2d(v1, v2);

            // Act.
            Line2d[] result = testObject.Split(nonIntersectingLine);

            // Assert.
            Assert.Null(result);
        }
Ejemplo n.º 3
0
        private bool CollisionSegments(Line2d line1, Line2d line2, out Vector2 point) // The point of intersection of two segments
        {
            point = Vector2.Zero;
            float ua, ub;

            if (!GetUaUb(line1, line2, out ua, out ub))
            {
                return(false);
            }
            if ((0.0f < ua) && (ua < 1.0f) && (0.0f < ub) && (ub < 1.0f))
            {
                point.X = line1.Point0.X + (line1.Point1.X - line1.Point0.X) * ub;
                point.Y = line1.Point0.Y + (line1.Point1.Y - line1.Point0.Y) * ub;
                return(true);
            }
            return(false);
        }
Ejemplo n.º 4
0
        public void ClassifyPointToLine_GivenPointBehind_ShouldReturnBehind(
            double v1x, double v1y,
            double v2x, double v2y,
            double px, double py)
        {
            // Arrange.
            var vertex1 = new Point2d(v1x, v1y);
            var vertex2 = new Point2d(v2x, v2y);
            var line    = new Line2d(vertex1, vertex2);
            var point   = new Point2d(px, py);

            // Act.
            PointClassifier.Classification result = PointClassifier.ClassifyPointToLine(point, line);

            // Assert.
            Assert.AreEqual(PointClassifier.Classification.Behind, result);
        }
        public static Dictionary <string, object> SplitByLine(Polygon2d polyOutline, Line2d inputLine, double distance = 5)
        {
            if (!ValidateObject.CheckPoly(polyOutline))
            {
                return(null);
            }
            List <Point2d> polyOrig   = polyOutline.Points;
            List <Point2d> poly       = PolygonUtility.SmoothPolygon(polyOrig, BuildLayout.SPACING);
            Line2d         splitLine  = new Line2d(inputLine);
            Point2d        centerPoly = PointUtility.CentroidInPointLists(poly);
            bool           checkSide  = ValidateObject.CheckPointSide(splitLine, centerPoly);
            int            orient     = ValidateObject.CheckLineOrient(splitLine);

            if (orient == 0)
            {
                if (!checkSide)
                {
                    splitLine = LineUtility.Move(splitLine, 0, -1 * distance);
                }
                else
                {
                    splitLine = LineUtility.Move(splitLine, 0, 1 * distance);
                }
            }
            else
            {
                if (checkSide)
                {
                    splitLine = LineUtility.Move(splitLine, -1 * distance, 0);
                }
                else
                {
                    splitLine = LineUtility.Move(splitLine, 1 * distance, 0);
                }
            }

            Dictionary <string, object> intersectionReturn = MakeIntersections(poly, splitLine, BuildLayout.SPACING);
            List <Polygon2d>            splittedPoly       = (List <Polygon2d>)intersectionReturn["PolyAfterSplit"];

            return(new Dictionary <string, object>
            {
                { "PolyAfterSplit", (splittedPoly) },
                { "SplitLine", (splitLine) }
            });
        }
Ejemplo n.º 6
0
    public void DrawRectangleOutline(Vector2 topLeft, Vector2 bottomRight, PackedLinearColorA color)
    {
        topLeft.X     += 0.5f;
        topLeft.Y     += 0.5f;
        bottomRight.X -= 0.5f;
        bottomRight.Y -= 0.5f;

        var topRight   = new Vector2(bottomRight.X, topLeft.Y);
        var bottomLeft = new Vector2(topLeft.X, bottomRight.Y);

        Span <Line2d> lines = stackalloc Line2d[4];

        lines[0] = new Line2d(topLeft, topRight, color);
        lines[1] = new Line2d(topRight, bottomRight, color);
        lines[2] = new Line2d(bottomRight, bottomLeft, color);
        lines[3] = new Line2d(bottomLeft, topLeft, color);
        DrawLines(lines);
    }
        // Removes the lines which are on the poly lines
        internal static List <Line2d> RemoveDuplicateslinesWithPoly(Polygon2d poly, List <Line2d> lineList)
        {
            List <Line2d> cleanLineList = new List <Line2d>();
            List <bool>   duplicateList = new List <bool>();

            for (int i = 0; i < lineList.Count; i++)
            {
                Line2d line = new Line2d(lineList[i].StartPoint, lineList[i].EndPoint);
                cleanLineList.Add(line);
                duplicateList.Add(false);
            }

            for (int i = 0; i < poly.Points.Count; i++)
            {
                int b = i + 1;
                if (i == poly.Points.Count - 1)
                {
                    b = 0;
                }
                Line2d lineA = new Line2d(poly.Points[i], poly.Points[b]);
                for (int j = 0; j < lineList.Count; j++)
                {
                    Line2d lineB    = lineList[j];
                    bool   checkAdj = GraphicsUtility.LineAdjacencyCheck(lineA, lineB);
                    if (checkAdj)
                    {
                        duplicateList[j] = true;
                        break;
                    } // end of if loop
                }     // end of 2nd for loop
            }         // end of 1st for loop

            int count = 0;

            for (int i = 0; i < duplicateList.Count; i++)
            {
                if (duplicateList[i] == true)
                {
                    cleanLineList.RemoveAt(i - count);
                    count += 1;
                }
            }
            return(cleanLineList);
        }
        //offsets an input line by a given distance
        internal static int DirectionForPointInPoly(Line2d lineInp, Polygon2d poly, double distance)
        {
            if (lineInp == null || !ValidateObject.CheckPoly(poly))
            {
                return(0);
            }
            Point2d midPt = LineMidPoint(lineInp);
            Point2d pt1   = OffsetLinePoint(lineInp, midPt, distance);
            Point2d pt2   = OffsetLinePoint(lineInp, midPt, -1 * distance);

            if (GraphicsUtility.PointInsidePolygonTest(poly, pt1))
            {
                return(1);
            }
            else
            {
                return(-1);
            }
        }
Ejemplo n.º 9
0
        //################################################################################################################
        //this class stores methods realted to GraphicsUtility class which needs to be tested further for reliability
        //################################################################################################################

        // checks if two lines are collinear - not using
        internal static bool CheckLineCollinear(Line2d lineA, Line2d lineB)
        {
            Point2d p1 = lineA.StartPoint;
            Point2d p2 = lineA.EndPoint;
            Point2d q1 = lineB.StartPoint;
            Point2d q2 = lineB.EndPoint;

            // Find the four orientations needed for general and special cases
            int o1 = GraphicsUtility.Orientation(p1, q1, p2);
            int o2 = GraphicsUtility.Orientation(p1, q1, q2);
            int o3 = GraphicsUtility.Orientation(p2, q2, p1);
            int o4 = GraphicsUtility.Orientation(p2, q2, q1);

            // General case
            if (o1 != o2 && o3 != o4)
            {
                return(false);
            }
            // p1, q1 and p2 are colinear and p2 lies on segment p1q1
            if (o1 == 0 && ValidateObject.CheckOnSegment(p1, p2, q1))
            {
                return(true);
            }

            // p1, q1 and p2 are colinear and q2 lies on segment p1q1
            if (o2 == 0 && ValidateObject.CheckOnSegment(p1, q2, q1))
            {
                return(true);
            }

            // p2, q2 and p1 are colinear and p1 lies on segment p2q2
            if (o3 == 0 && ValidateObject.CheckOnSegment(p2, p1, q2))
            {
                return(true);
            }

            // p2, q2 and q1 are colinear and q1 lies on segment p2q2
            if (o4 == 0 && ValidateObject.CheckOnSegment(p2, q1, q2))
            {
                return(true);
            }
            return(false); // Doesn't fall in any of the above cases
        }
        //finds the closest point to a line from a point list
        public static Point2d ClosestPointToLine(List <Point2d> pt, Line2d line)
        {
            double a     = line.StartPoint.Y - line.EndPoint.Y;
            double b     = line.EndPoint.X - line.StartPoint.X;
            double c     = line.StartPoint.X * line.EndPoint.Y - line.EndPoint.X * line.StartPoint.Y;
            int    index = 0;
            double min   = Math.Abs(a * pt[0].X + b * pt[0].Y + c);

            for (int i = 1; i < pt.Count; i++)
            {
                double dist = Math.Abs(a * pt[i].X + b * pt[i].Y + c);
                if (dist < min)
                {
                    index = i;
                    min   = dist;
                }
            }
            return(pt[index]);
        }
        internal static Polygon2d AddpointToPoly(Polygon2d poly, int lineId = 0)
        {
            if (!ValidateObject.CheckPoly(poly))
            {
                return(null);
            }
            List <Point2d> ptList = new List <Point2d>();

            for (int i = 0; i < poly.Points.Count; i++)
            {
                if (i == lineId)
                {
                    Line2d line = poly.Lines[lineId];
                }

                ptList.Add(poly.Points[i]);
            }
            return(null);
        }
Ejemplo n.º 12
0
        public void AngleOfLine()
        {
            var line1 = new Line2d(new Point2d(0, 0), new Point2d(100, 0));
            var angle = line1.Angle;

            Assert.AreEqual(90, angle);

            var line2 = new Line2d(new Point2d(0, 0), new Point2d(100, 100));

            angle = line2.Angle;

            Assert.AreEqual(45, angle);

            var line3 = new Line2d(new Point2d(0, 0), new Point2d(0, 100));

            angle = line3.Angle;

            Assert.AreEqual(0, angle);

            var line4 = new Line2d(new Point2d(0, 0), new Point2d(-100, 100));

            angle = line4.Angle;

            Assert.AreEqual(315, angle);

            var line5 = new Line2d(new Point2d(0, 0), new Point2d(-100, 0));

            angle = line5.Angle;

            Assert.AreEqual(270, angle);

            var line6 = new Line2d(new Point2d(0, 0), new Point2d(-100, -100));

            angle = line6.Angle;

            Assert.AreEqual(225, angle);

            var line7 = new Line2d(new Point2d(0, 0), new Point2d(0, -100));

            angle = line7.Angle;

            Assert.AreEqual(180, angle);
        }
    public static void Test()
    {
        Line2d line1 = new Line2d();

        line1.m_point1 = new Vector2L(0, 0);
        line1.m_point2 = new Vector2L(100, 100);

        Line2d line2 = new Line2d();

        line2.m_point1 = new Vector2L(0, 100);
        line2.m_point2 = new Vector2L(100, 0);

        Vector2L intersectionPoint = new Vector2L();

        if (Line2dWithLine2d(line1, line2, ref intersectionPoint))
        {
            Debug.Log("双线相交 交点 " + intersectionPoint);
        }
        else
        {
            Debug.Log("双线没有相交");
        }

        List <Vector2L> pointList = new List <Vector2L> {
            new Vector2L(-4.5f, -10f),
            new Vector2L(-4.5f, 10f),
            new Vector2L(4.5f, 10f),
            new Vector2L(4.5f, -10f)
        };
        Convex2d convex1 = new Convex2d(new Vector2L(-5, 0), QuaternionL.Euler(Vector3L.zero), pointList);
        Convex2d convex2 = new Convex2d(new Vector2L(+5, 0), QuaternionL.Euler(Vector3L.zero), pointList);

        Debug.Log("凸多边形相交测试1 " + (Convex2dWithConvex2d(convex1, convex2, false, true) != null));
        Convex2d convex3 = new Convex2d(new Vector2L(+5, 0), QuaternionL.Euler(new Vector3L(0, -90, 0)), pointList);

        Debug.Log("凸多边形相交测试2 " + (Convex2dWithConvex2d(convex1, convex3, false, true) != null));

        Circle2d circle = new Circle2d(new Vector3L(-5, 0), 5);

        Debug.Log("圆与凸多边形相交测试1 " + (Circle2dWithConvex2d(circle, convex2, false, true) != null));
        Debug.Log("圆与凸多边形相交测试2 " + (Circle2dWithConvex2d(circle, convex3, false, true) != null));
    }
Ejemplo n.º 14
0
        private void CreatePoints4()
        {
            double a = 4;
            double b = 7;

            Line2d plane = new Line2d(a, b);

            double xSpace = 1.0;

            int xPointCount = 1;

            TestPoints.Clear();

            for (int i = 0; i < xPointCount; i++)
            {
                double x = xSpace * i;
                double y = plane.GetY(x);
                TestPoints.Add(new Vector2(x, y));
            }
        }
Ejemplo n.º 15
0
        private void CreatePoints3()
        {
            double a = 0.5;
            double b = 7;

            Line2d plane = new Line2d(a, b);

            double xSpace = 1.0;

            int xPointCount = 200;

            TestPoints.Clear();

            for (int i = 0; i < xPointCount; i++)
            {
                double x = xSpace * i + NextRangedRandomNumber(xSpace);
                double y = plane.GetY(x) + NextRangedRandomNumber(20);
                TestPoints.Add(new Vector2(x, y));
            }
        }
Ejemplo n.º 16
0
        /// <summary>
        /// 八边形绘图
        /// </summary>
        /// <param name="AnchorPoint">锚点,八边形下中心点</param>
        /// <param name="Height">总高</param>
        /// <param name="Width">总宽</param>
        /// <param name="F1x">下倒角,x方向</param>
        /// <param name="F1y">下倒角,y方向</param>
        /// <param name="F2x">上倒角,x方向</param>
        /// <param name="F2y">上倒角,y方向</param>
        public static Polyline Plot8(Database db, Point2d AnchorPoint, double Height, double Width,
                                     double F1x = 50, double F1y = 50, double F2x = 200, double F2y = 100)
        {
            Polyline PL1 = new Polyline()
            {
                Closed = true
            };

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable       blockTbl   = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord modelSpace = tr.GetObject(blockTbl[BlockTableRecord.ModelSpace],
                                                           OpenMode.ForWrite) as BlockTableRecord;

                Line2d  AxisY = new Line2d(AnchorPoint, AnchorPoint.Convert2D(0, 1));
                Point2d p0, p1, p2, p3, p4, p5, p6, p7;

                p0 = AnchorPoint.Convert2D(-0.5 * Width + F1x, 0);
                p1 = p0.Mirror(AxisY);
                p2 = p1.Convert2D(F1x, F1y);
                p3 = p2.Convert2D(0, Height - F1y - F2y);
                p4 = p3.Convert2D(-F2x, F2y);
                p5 = p4.Mirror(AxisY);
                p6 = p3.Mirror(AxisY);
                p7 = p2.Mirror(AxisY);
                PL1.AddVertexAt(0, p0, 0, 0, 0);
                PL1.AddVertexAt(1, p1, 0, 0, 0);
                PL1.AddVertexAt(2, p2, 0, 0, 0);
                PL1.AddVertexAt(3, p3, 0, 0, 0);
                PL1.AddVertexAt(4, p4, 0, 0, 0);
                PL1.AddVertexAt(5, p5, 0, 0, 0);
                PL1.AddVertexAt(6, p6, 0, 0, 0);
                PL1.AddVertexAt(7, p7, 0, 0, 0);

                modelSpace.AppendEntity(PL1);
                tr.AddNewlyCreatedDBObject(PL1, true);
                tr.Commit();
            }

            return(PL1);
        }
Ejemplo n.º 17
0
        public void ClassifyLineToLine_GivenCoincidentLines_ShouldReturnCoincident(
            double line1v1x, double line1v1y,
            double line1v2x, double line1v2y,
            double line2v1x, double line2v1y,
            double line2v2x, double line2v2y)
        {
            // Arrange.
            var line1vertex1 = new Point2d(line1v1x, line1v1y);
            var line1vertex2 = new Point2d(line1v2x, line1v2y);
            var line2vertex1 = new Point2d(line2v1x, line2v1y);
            var line2vertex2 = new Point2d(line2v2x, line2v2y);

            var line1 = new Line2d(line1vertex1, line1vertex2);
            var line2 = new Line2d(line2vertex1, line2vertex2);

            // Act.
            LineClassifier.Classification result = LineClassifier.ClassifyLineToLine(line1, line2);

            // Assert.
            Assert.AreEqual(LineClassifier.Classification.Coincident, result);
        }
Ejemplo n.º 18
0
        public void ClassifyLineToLine_GivenLine1SpanningLine2_ShouldReturnIntersecting(
            double line1v1x, double line1v1y,
            double line1v2x, double line1v2y,
            double line2v1x, double line2v1y,
            double line2v2x, double line2v2y)
        {
            // Arrange.
            var line1vertex1 = new Point2d(line1v1x, line1v1y);
            var line1vertex2 = new Point2d(line1v2x, line1v2y);
            var line2vertex1 = new Point2d(line2v1x, line2v1y);
            var line2vertex2 = new Point2d(line2v2x, line2v2y);

            var line1 = new Line2d(line1vertex1, line1vertex2);
            var line2 = new Line2d(line2vertex1, line2vertex2);

            // Act.
            LineClassifier.Classification result = LineClassifier.ClassifyLineToLine(line1, line2);

            // Assert.
            Assert.AreEqual(LineClassifier.Classification.Intersecting, result);
        }
Ejemplo n.º 19
0
        static double?LinearInterpolation(double[] x, double[] y, double xval)
        {
            double?zval = null;
            Line2d interpolant;
            int    lx = x.Length;
            int    ly = y.Length;

            if (lx < 2 || ly < 2)
            {
                return(zval);
            }
            if (lx != ly)
            {
                return(zval);
            }

            for (int i = 0; i < lx - 1; i++)
            {
                if (xval >= x[i] && xval < x[i + 1])
                {
                    interpolant = new Line2d(new Point2d(x[i], y[i]), new Point2d(x[i + 1], y[i + 1]));
                    return(interpolant.Interpolation(xval));
                }

                if (xval < x[0])
                {
                    interpolant = new Line2d(new Point2d(x[0], y[0]), new Point2d(x[1], y[1]));
                    return(interpolant.Interpolation(xval));
                }

                if (xval >= x[lx - 1])
                {
                    interpolant = new Line2d(new Point2d(x[lx - 2], y[lx - 2]), new Point2d(x[lx - 1], y[lx - 1]));
                    return(interpolant.Interpolation(xval));
                }
            }

            return(zval);
        }
Ejemplo n.º 20
0
        private void CreatePoints1()
        {
            double a = 1;
            double b = 2;

            Line2d plane = new Line2d(a, b);

            double xSpace = 1.0;

            int xPointCount = 10;

            List <Vector2> points = new List <Vector2>();

            for (int i = 0; i < xPointCount; i++)
            {
                double x = xSpace * i;
                double y = plane.GetY(x);
                points.Add(new Vector2(x, y));
            }

            TestPoints = points;
        }
Ejemplo n.º 21
0
        private void CreatePoints2()
        {
            double a = 1;
            double b = 2;

            Line2d plane = new Line2d(a, b);

            double xSpace = 1.0;

            int xPointCount = 100;

            List <Vector2> points = new List <Vector2>();

            for (int i = 0; i < xPointCount; i++)
            {
                double x = xSpace * i + NextRangedRandomNumber(xSpace);
                double y = plane.GetY(x) + NextRangedRandomNumber(5);
                points.Add(new Vector2(x, y));
            }

            TestPoints = points;
        }
Ejemplo n.º 22
0
        //checks a line if horizontal or vertical, 0 for horizontal, 1 for vertical
        internal static int CheckLineOrient(Line2d line)
        {
            if (line == null)
            {
                return(-1);
            }
            double x = Math.Round((line.StartPoint.X - line.EndPoint.X), 2);
            double y = Math.Round((line.StartPoint.Y - line.EndPoint.Y), 2);

            if (x == 0)
            {
                return(1);
            }
            else if (y == 0)
            {
                return(0);
            }
            else
            {
                return(-1); // was 0 prev
            }
        }
        //checks if two lines are same
        public static bool IsLineDuplicate(Line2d A, Line2d B)
        {
            bool   check = false;
            double eps   = 0.1;
            double mA    = (A.EndPoint.Y - A.StartPoint.Y) / (A.EndPoint.X - A.StartPoint.X);
            double mB    = (B.EndPoint.Y - B.StartPoint.Y) / (B.EndPoint.X - B.StartPoint.X);

            if ((mB - eps < mA && mA < mB + eps) || (mA - eps < mB && mB < mA + eps))
            {
                double intercA = A.StartPoint.Y - mA * A.StartPoint.X;
                double intercB = B.StartPoint.Y - mB * B.StartPoint.X;
                if ((intercA - eps < intercA && intercA < intercA + eps) || (intercB - eps < intercB && intercB < intercB + eps))
                {
                    check = true;
                }
                else
                {
                    check = false;
                }
            }
            return(check);
        }
Ejemplo n.º 24
0
        private Point2d ImaginaryIntersect(Point2d line1_pt1, Point2d line1_pt2, Point2d line2_pt1, Point2d line2_pt2)
        {
            Line2d line1 = new Line2d(line1_pt1, line1_pt2);
            Line2d line2 = new Line2d(line2_pt1, line2_pt2);

            double line1Ang = line1.Direction.Angle;
            double line2Ang = line2.Direction.Angle;

            double line1ConAng = line1Ang + Degrees_Radians_Conversion(180, false);
            double line2ConAng = line2Ang + Degrees_Radians_Conversion(180, false);

            Point2d RayLine1_pt1 = PolarPoint(line1_pt1, line1Ang, 10000);
            Point2d RayLine1_pt2 = PolarPoint(line1_pt1, line1ConAng, 10000);
            Line2d  RayLine1     = new Line2d(RayLine1_pt1, RayLine1_pt2);

            Point2d RayLine2_pt1 = PolarPoint(line2_pt1, line2Ang, 10000);
            Point2d RayLine2_pt2 = PolarPoint(line2_pt1, line2ConAng, 10000);
            Line2d  RayLine2     = new Line2d(RayLine2_pt1, RayLine2_pt2);

            Point2d[] col = RayLine1.IntersectWith(RayLine2);

            return(col[0]);
        }
Ejemplo n.º 25
0
        /// <summary>
        /// 求两个familyinstance的旋转中心
        /// </summary>
        /// <param name="pos1"></param>
        /// <param name="faceOri1"></param>
        /// <param name="pos2"></param>
        /// <param name="faceOri2"></param>
        /// <returns></returns>
        public static XYZ GetRotateCenter(XYZ pos1, XYZ faceOri1, XYZ pos2, XYZ faceOri2)
        {
            //求垂直平分线1
            Line pb1 = GetPerpendicularBisector(pos1, pos2);
            //求垂直平分线2
            XYZ  pos3 = pos1 + faceOri1;
            XYZ  pos4 = pos2 + faceOri2;
            Line pb2  = GetPerpendicularBisector(pos3, pos4);

            Line2d line1 = pb1.ToLine2d();
            Line2d line2 = pb2.ToLine2d();

            //求垂直平分线的交点
            IntrLine2Line2 inter = new IntrLine2Line2(line1, line2);

            inter.Compute();
            if (inter.Quantity != 0)
            {
                Vector2d p  = inter.Point;
                XYZ      _p = new XYZ(p.x, p.y, pos1.Z);
                return(_p);
            }
            return(null);
        }
        //extends both  ends of a line
        public static Line2d ExtendLine(Line2d line, double extend = 0)
        {
            if (extend == 0)
            {
                extend = 10000;
            }
            double startPtX = 0, startPtY = 0, endPtX = 0, endPtY = 0;

            if (ValidateObject.CheckLineOrient(line) == 1)
            {
                startPtX = line.StartPoint.X;
                startPtY = line.StartPoint.Y - extend;
                endPtX   = line.EndPoint.X;
                endPtY   = line.EndPoint.Y + extend;
            }
            else
            {
                startPtX = line.StartPoint.X - extend;
                startPtY = line.StartPoint.Y;
                endPtX   = line.EndPoint.X + extend;
                endPtY   = line.EndPoint.Y;
            }
            return(new Line2d(new Point2d(startPtX, startPtY), new Point2d(endPtX, endPtY)));
        }
Ejemplo n.º 27
0
        public void Constructor_GivenLines_ShouldBuildTree()
        {
            // Arrange.

            /*           (r2)
             *            |
             *    (E1)---------(E2)
             *            |
             * (B1)--(B2) | (C1)--(C2)
             *            |
             * (A1)--(A2) | (D1)--(D2)
             *           (r1)
             *    (F1)---------(F2)
             */
            var lines = new List <Line2d>
            {
                new Line2d(new Point2d(-5, -5), new Point2d(-2, -5)), // A
                new Line2d(new Point2d(-5, -8), new Point2d(-2, -8)), // B
                new Line2d(new Point2d(0, -8), new Point2d(2, -8)),   // C
                new Line2d(new Point2d(0, -5), new Point2d(2, -5)),   // D
                new Line2d(new Point2d(-3, -9), new Point2d(1, -9)),  // E
                new Line2d(new Point2d(-3, 1), new Point2d(1, 1))     // F
            };

            var ray = new Line2d(
                new Point2d(-1, -1),
                new Point2d(-1, -10));

            var testObject = new Tree(lines);

            // Act.
            Line2d result = testObject.FindFirstIntersectingLine(ray);

            // Assert.
            Assert.NotNull(result);
        }
Ejemplo n.º 28
0
        internal void CalcNL(Mesh blackMesh)
        {
            if (blackMesh == null)
            {
                return;
            }

            Vertex           vrtx;
            TriangleQuadTree meshTree = new TriangleQuadTree(blackMesh);

            TriangleNet.Topology.Triangle trgl = (TriangleNet.Topology.Triangle)meshTree.Query(X, Y);
            if (trgl == null)
            {
                Dictionary <Vertex, double> valuePairs = new Dictionary <Vertex, double>();
                Line2d ln;
                foreach (Vertex item in blackMesh.Vertices)
                {
                    ln = new Line2d(new Point2d(X, Y), new Point2d(item.X, item.Y));
                    valuePairs.Add(item, ln.Length);
                }
                IOrderedEnumerable <KeyValuePair <Vertex, double> > selected = from v in valuePairs // определяем каждый объект как
                                                                               orderby v.Value      // упорядочиваем по возрастанию
                                                                               select v;            // выбираем объект
                List <KeyValuePair <Vertex, double> > lst = selected.ToList();
                foreach (TriangleNet.Topology.Triangle item in blackMesh.Triangles)
                {
                    if (item.Contains(lst[0].Key) && item.Contains(lst[1].Key))
                    {
                        trgl = item; break;
                    }
                }
            }
            vrtx = new Vertex(X, Y, Number, 2);
            Interpolation.InterpolateAttributes(vrtx, trgl, 1);
            NL = Math.Round(vrtx.Attributes[0], 3);
        }
Ejemplo n.º 29
0
        private bool GetBaseLine()
        {
            var ptRes = Ac.Editor.GetPoint("\r\n" + AppServices.Strings.EnterStartPoint);

            if (!ptRes.IsOK())
            {
                return(false);
            }

            var startPt = ptRes.Value;

            var epPrtOpts = Ac.Editor.GetPromptPointOptions("\r\n" + AppServices.Strings.EnterEndPoint, startPt, true);

            ptRes = Ac.Editor.GetPoint(epPrtOpts);
            if (!ptRes.IsOK())
            {
                return(false);
            }

            var endPt = ptRes.Value;

            this.BaseLine = new Line2d(startPt.Convert2d(), endPt.Convert2d());
            return(true);
        }
Ejemplo n.º 30
0
        public void Slice(DynamicRenderMesh mesh, Camera camera)
        {
            slicePointsDictionary.Clear();
            verticesDictionary.Clear();
            slicePoints.Clear();
            vertices.Clear();
            texCoords.Clear();
            indices.Clear();
            triangles.Clear();
            ResultMeshes.Clear();

            FillVertices(mesh, camera);
            Vector2 A = new Vector2(99999.0f, 99999.0f), B = new Vector2(-99999.0f, -99999.0f);
            var     tempLine      = new Line2d();
            var     workedIndices = new List <int>();
            var     tempIndices   = new List <int>();

            foreach (var line in Lines)
            {
                for (var i = 0; i < 2; i++)
                {
                    if (line.A[i] < A[i])
                    {
                        A[i] = line.A[i];
                    }
                    if (line.B[i] > B[i])
                    {
                        B[i] = line.B[i];
                    }
                }
            }
            for (var i = 0; i < indices.Count / 3; i++)
            {
                var index  = i * 3;
                var point0 = vertices[indices[index]];
                var point1 = vertices[indices[index + 1]];
                var point2 = vertices[indices[index + 2]];



                if (!CheckAABB(ref point0, ref point1, ref point2, ref A, ref B))
                {
                    for (var j = 0; j < 3; j++)
                    {
                        tempIndices.Add(indices[index + j]);
                    }
                    continue;
                }

                for (var j = 0; j < 3; j++)
                {
                    workedIndices.Add(indices[index + j]);
                }
            }

            if (workedIndices.Count == 0)
            {
                return;
            }

            var triangle                  = new Vector3[3];
            var triangleT                 = new Vector2[3];
            var tempCollisions            = new List <Vector3>();
            var tempTexCoords             = new List <Vector2>();
            var tempCollisionsEdgeIndices = new List <int>();
            var newTriangles              = new List <int>();
            var info0 = CollisionInfo.Zero;
            var info1 = CollisionInfo.Zero;

            for (var i = 0; i < sliceLines.Count; i++)
            {
                var line           = Lines[i];
                var sliceLine      = sliceLines[i];
                var trianglesCount = workedIndices.Count / 3;
                for (var j = 0; j < trianglesCount; j++)
                {
                    var index = j * 3;
                    for (var l = 0; l < 3; l++)
                    {
                        triangle[l]  = vertices[workedIndices[index + l]];
                        triangleT[l] = texCoords[workedIndices[index + l]];
                    }

                    info0 = CollisionInfo.Zero;
                    info1 = CollisionInfo.Zero;
                    tempCollisions.Clear();
                    tempTexCoords.Clear();
                    tempCollisionsEdgeIndices.Clear();
                    newTriangles.Clear();
                    //looking for a point / intersection point of the triangle and line
                    for (int k = 0, l = 2; k < 3; l = k, k++)
                    {
                        if (info1.Type != CollisionType.CT_NONE)
                        {
                            break;
                        }
                        var tPoint0 = triangle[l];
                        var tPoint1 = triangle[k];

                        var tTexCoord0 = triangleT[l];
                        var tTexCoord1 = triangleT[k];

                        tempLine.Point0.X = tPoint0.X;
                        tempLine.Point0.Y = tPoint0.Y;
                        tempLine.Point1.X = tPoint1.X;
                        tempLine.Point1.Y = tPoint1.Y;

                        float ua, ub;
                        if (!GetUaUb(tempLine, line, out ua, out ub))
                        {
                            //lines coincide?
                            //Verify whether some point belongs line segment tempLine
                            //if find - get result and break.
                        }
                        else
                        {
                            if (ub < 0.0f || ub > 1.0f)
                            {
                                continue;
                            }
                            var collisionPoint    = tPoint0 + (tPoint1 - tPoint0) * ub;
                            var collisionTexCoord = tTexCoord0 + (tTexCoord1 - tTexCoord0) * ub;
                            if (tempCollisions.Count == 0 || !PointsCompare.Equals(tempCollisions[0], collisionPoint))
                            {
                                tempCollisions.Add(collisionPoint);
                                tempTexCoords.Add(collisionTexCoord);
                                tempCollisionsEdgeIndices.Add(l);
                            }
                            if (ua < 0.0f || ua > 1.0f)
                            {
                                continue;
                            }

                            var     pointType = CollisionType.CT_VERTEX;
                            Vector3 point;
                            Vector2 texCoord;
                            var     pointIndex = -1;
                            var     edgeIndex  = -1;

                            if (ub > 0.0f)
                            {
                                if (ub < 1.0f)
                                {
                                    pointType = CollisionType.CT_EDGE;
                                    point     = tempCollisions.Last();
                                    texCoord  = tempTexCoords.Last();
                                    edgeIndex = l;
                                }
                                else
                                {
                                    point      = tPoint1;
                                    texCoord   = tTexCoord1;
                                    pointIndex = workedIndices[index + k];
                                }
                            }
                            else
                            {
                                point      = tPoint0;
                                texCoord   = tTexCoord0;
                                pointIndex = workedIndices[index + l];
                            }
                            if (info0.Type == CollisionType.CT_NONE)
                            {
                                info0.PointIndex = pointIndex;
                                info0.Type       = pointType;
                                info0.Position   = point;
                                info0.TexCoord   = texCoord;
                                info0.EdgeIndex  = edgeIndex;
                            }
                            else
                            {
                                if (pointIndex == -1 || info0.PointIndex != pointIndex)
                                {
                                    info1.PointIndex = pointIndex;
                                    info1.Type       = pointType;
                                    info1.Position   = point;
                                    info1.TexCoord   = texCoord;
                                    info1.EdgeIndex  = edgeIndex;
                                }
                            }
                        }
                    }

                    if (info1.Type == CollisionType.CT_NONE)
                    {
                        if (tempCollisions.Count == 0)
                        {
                            if (info0.Type == CollisionType.CT_NONE)
                            {
                                continue;
                            }
                        }
                        else
                        {
                            if (tempCollisions.Count > 1)
                            {
                                //Perhaps the point inside the triangle
                                var dir = line.Direction;
                                for (var l = 0; l < 2; l++)
                                {
                                    var p = l == 0 ? line.Point0 : line.Point1;
                                    if (PointInTriangle(ref triangle[0], ref triangle[1], ref triangle[2], ref p))
                                    {
                                        var v0 = tempCollisions[1].Xy - tempCollisions[0].Xy;
                                        var v1 = p - tempCollisions[0].Xy;
                                        var k  = (v1.Length / v0.Length);
                                        var z  = tempCollisions[0].Z + (tempCollisions[1].Z - tempCollisions[0].Z) * k;
                                        var t  = tempTexCoords[0] + (tempTexCoords[1] - tempTexCoords[0]) * k;
                                        if (info0.Type == CollisionType.CT_NONE)
                                        {
                                            info0.Type     = CollisionType.CT_INSIDE;
                                            info0.Position = new Vector3(p.X, p.Y, z);
                                            info0.TexCoord = t;
                                            if (Vector2.Dot(dir, v0) > 0.0f)
                                            {
                                                info0.EdgeIndex = tempCollisionsEdgeIndices[0];
                                            }
                                            else
                                            {
                                                info0.EdgeIndex = tempCollisionsEdgeIndices[1];
                                            }
                                            tempCollisionsEdgeIndices.Remove(info0.EdgeIndex);
                                        }
                                        else
                                        {
                                            info1.Type      = CollisionType.CT_INSIDE;
                                            info1.Position  = new Vector3(p.X, p.Y, z);
                                            info1.TexCoord  = t;
                                            info1.EdgeIndex = tempCollisionsEdgeIndices[0];
                                        }
                                    }
                                }
                            }
                        }
                    }

                    if (info0.Type == CollisionType.CT_NONE)
                    {
                        continue;
                    }
                    //Create new triangles, if we have two points of intersection, and they are not vertices
                    int pi1 = 0, pi0 = 0;
                    if (info1.Type != CollisionType.CT_NONE && (info0.Type != CollisionType.CT_VERTEX || info1.Type != CollisionType.CT_VERTEX))
                    {
                        if (info1.Type == CollisionType.CT_VERTEX ||
                            (info1.Type == CollisionType.CT_EDGE && info0.Type == CollisionType.CT_INSIDE) ||
                            (info1.Type == CollisionType.CT_EDGE && info0.Type == CollisionType.CT_EDGE && (info0.EdgeIndex + 1) % 3 != info1.EdgeIndex) ||
                            (info0.Type == CollisionType.CT_INSIDE && info1.Type == CollisionType.CT_INSIDE && (info0.EdgeIndex + 1) % 3 != info1.EdgeIndex))
                        {
                            var temp = info1;
                            info1 = info0;
                            info0 = temp;
                        }

                        if (!verticesDictionary.TryGetValue(info1.Position, out pi1))
                        {
                            pi1 = vertices.Count;
                            vertices.Add(info1.Position);
                            texCoords.Add(info1.TexCoord);
                            verticesDictionary.Add(info1.Position, pi1);
                        }

                        if (info0.Type == CollisionType.CT_VERTEX) //One point of intersection coincides with the vertex
                        {
                            pi0 = info0.PointIndex;
                            int i0 = workedIndices[index], i1 = workedIndices[index + 1], i2 = workedIndices[index + 2];
                            if (i0 == info0.PointIndex)
                            {
                                i0 = i2;
                                i2 = i1;
                            }
                            else
                            {
                                if (i2 == info0.PointIndex)
                                {
                                    i2 = i0;
                                    i0 = i1;
                                }
                            }
                            i1 = info0.PointIndex;

                            newTriangles.AddRange(new[] { i0, i1, pi1,
                                                          i1, i2, pi1 });
                            if (info1.Type == CollisionType.CT_INSIDE) //The second point inside the triangle
                            {
                                newTriangles.AddRange(new[] { i2, i0, pi1 });
                            }
                        }
                        else
                        {
                            if (!verticesDictionary.TryGetValue(info0.Position, out pi0))
                            {
                                pi0 = vertices.Count;
                                vertices.Add(info0.Position);
                                texCoords.Add(info0.TexCoord);
                                verticesDictionary.Add(info0.Position, pi0);
                            }

                            if (info1.Type != info0.Type) //One point crosses the brink, the second inside the triangle
                            {
                                var prev = info0.EdgeIndex == 0 ? 2 : info0.EdgeIndex - 1;
                                prev = workedIndices[index + prev];
                                var next = info0.EdgeIndex == 2 ? 0 : info0.EdgeIndex + 1;
                                next = workedIndices[index + next];
                                var curr = workedIndices[index + info0.EdgeIndex];
                                newTriangles.AddRange(new[] { prev, curr, pi1,
                                                              curr, pi0, pi1,
                                                              pi0, next, pi1,
                                                              next, prev, pi1 });
                            }
                            else
                            {
                                var c0 = workedIndices[index + info0.EdgeIndex];
                                var c1 = workedIndices[index + info1.EdgeIndex];
                                var c2 = workedIndices[index + ((info1.EdgeIndex + 1) % 3)];

                                if (info0.Type == CollisionType.CT_EDGE)
                                {
                                    newTriangles.AddRange(new[] { c0, pi0, pi1,
                                                                  pi0, c1, pi1,
                                                                  pi1, c2, c0 });
                                }
                                else
                                {
                                    newTriangles.AddRange(new[] { c0, c1, pi0,
                                                                  c1, pi1, pi0,
                                                                  c1, c2, pi1,
                                                                  c2, c0, pi1,
                                                                  c0, pi0, pi1 });
                                }
                            }
                        }
                    }
                    int        slicePointIndex;
                    SlicePoint slicePoint;
                    for (var l = 0; l < 2; l++)
                    {
                        if (l == 1 && info1.Type == CollisionType.CT_NONE)
                        {
                            break;
                        }
                        var position   = l == 0 ? info0.Position.Xy : info1.Position.Xy;
                        var pointIndex = l == 0 ? pi0 : pi1;
                        if (!slicePointsDictionary.TryGetValue(position, out slicePointIndex))
                        {
                            slicePoint = new SlicePoint
                            {
                                Coordinate = position
                            };
                            slicePoint.Lines.Add(sliceLine);
                            slicePoint.PreparePoint();
                            slicePointIndex = slicePoints.Count;
                            slicePoints.Add(slicePoint);
                            slicePointsDictionary.Add(position, slicePointIndex);
                        }
                        else
                        {
                            slicePoint = slicePoints[slicePointIndex];
                        }
                        if (!slicePoint.Indices.Contains(pointIndex))
                        {
                            slicePoint.Indices.Add(pointIndex);
                        }
                    }

                    if (newTriangles.Count > 0)
                    {
                        for (var l = 0; l < 3; l++)
                        {
                            workedIndices[index + l] = newTriangles[l];
                        }
                        newTriangles.RemoveRange(0, 3);
                        workedIndices.InsertRange(index, newTriangles);
                        var count = (newTriangles.Count / 3);
                        j += count;
                        trianglesCount += count;
                    }
                }
            }

            for (var i = 0; i < workedIndices.Count / 3; i++)
            {
                var index = i * 3;
                var t     = new Triangle();
                for (var j = 0; j < 3; j++)
                {
                    t.Indices[j] = workedIndices[index + j];
                }
                triangles.Add(i, new TrianleConnections
                {
                    Triangle = t
                });
            }

            var ind          = new List <int>();
            var tempTriangle = new Triangle();

            tempTriangle.Indices[1] = -1;
            foreach (var point in slicePoints)
            {
                point.PreparePoint();
                foreach (var index in point.Indices)
                {
                    ind.Clear();
                    ind.Add(index);
                    tempTriangle.Indices[0] = index;
                    //Duplicate the verticle several times
                    for (var i = 1; i < point.Directions.Count; i++)
                    {
                        ind.Add(vertices.Count);
                        vertices.Add(vertices[index]);
                        texCoords.Add(texCoords[index]);
                    }
                    foreach (var t in triangles)
                    {
                        var tr = t.Value.Triangle;
                        var id = Triangle.TriangleEquals(ref tempTriangle, ref tr);
                        if (id > -1)
                        {
                            var center = (vertices[tr.Indices[0]].Xy + vertices[tr.Indices[1]].Xy + vertices[tr.Indices[2]].Xy) / 3.0f;
                            var dir    = (center - point.Coordinate).Normalized();
                            var angle  = SlicePoint.GetAngle(ref dir);
                            var ii     = point.Directions.Count - 1;
                            for (var j = 0; j < point.Directions.Count; j++)
                            {
                                if (angle < point.Directions[j])
                                {
                                    break;
                                }
                                ii = j;
                            }
                            tr.Indices[id] = ind[ii];
                        }
                    }
                }
            }

            var invTransform = mesh.Transform * camera.ViewMatrix;

            invTransform.Invert();
            for (var i = 0; i < vertices.Count; i++)
            {
                vertices[i] = Vector3.Transform(vertices[i], invTransform);
            }

            workedIndices.Clear();

            foreach (var t in triangles)
            {
                foreach (var i in t.Value.Triangle.Indices)
                {
                    workedIndices.Add(i);
                }
            }
            workedIndices.AddRange(tempIndices);
            triangleConnections.Clear();
            triangles.Clear();

            for (var i = 0; i < workedIndices.Count / 3; i++)
            {
                var index = i * 3;
                var t     = new Triangle();
                for (var j = 0; j < 3; j++)
                {
                    t.Indices[j] = workedIndices[index + j];
                    List <int> l;
                    if (!triangleConnections.TryGetValue(t.Indices[j], out l))
                    {
                        l = new List <int>();
                        triangleConnections.Add(t.Indices[j], l);
                    }
                    l.Add(i);
                }
                triangles.Add(i, new TrianleConnections
                {
                    Triangle = t
                });
            }

            var mainMesh = true;

            while (triangles.Count > 0)
            {
                foundedTriangles.Clear();
                FillTriangles(triangles.First().Key);

                if (mainMesh)
                {
                    mesh.Create(vertices, texCoords, foundedTriangles, mesh.Material.DiffuseTextureMap, mesh.Material.TransparentTextureMap, mesh.TextureAngle, mesh.TextureSize);
                    mainMesh = false;
                }
                else
                {
                    var tmpMesh = new DynamicRenderMesh(MeshType.Hair);
                    tmpMesh.Create(vertices, texCoords, foundedTriangles, mesh.Material.DiffuseTextureMap, mesh.Material.TransparentTextureMap, mesh.TextureAngle, mesh.TextureSize);
                    tmpMesh.Transform             = mesh.Transform;
                    tmpMesh.Material.DiffuseColor = mesh.Material.DiffuseColor;
                    tmpMesh.MeshAngle             = mesh.MeshAngle;
                    tmpMesh.MeshSize = mesh.MeshSize;

                    var info   = tmpMesh.GetMeshInfo();
                    var center = Vector3.Zero;
                    var scale  = PickingController.GetHairScale(ProgramCore.Project.ManType);
                    foreach (var vert in info.Positions)
                    {
                        center.X += vert.X * scale;
                        center.Y += vert.Y * scale;
                        center.Z += vert.Z * scale;
                    }
                    center          /= info.Positions.Count;
                    tmpMesh.Position = center;

                    ResultMeshes.Add(tmpMesh);
                }
            }
        }
Ejemplo n.º 31
0
        public static LineSegment2d[] GetTangentsTo(
            [NotNull] this CircularArc2d arc,
            [NotNull] CircularArc2d other,
            TangentType flags)
        {
            // check if a circle is inside the other
            var dist = arc.Center.GetDistanceTo(other.Center);

            if (dist - Math.Abs(arc.Radius - other.Radius) <= Tolerance.Global.EqualPoint)
            {
                return(null);
            }

            // check if circles overlap
            var overlap = arc.Radius + other.Radius >= dist;

            if (overlap && flags == TangentType.Inner)
            {
                return(null);
            }

            CircularArc2d tmp1;

            Point2d[] inters;
            Vector2d  vec1, vec2, vec = other.Center - arc.Center;
            int       i, j;
            var       result = new LineSegment2d[(int)flags == 3 && !overlap ? 4 : 2];

            // outer tangents
            if ((flags & TangentType.Outer) > 0)
            {
                if (Math.Abs(arc.Radius - other.Radius) < 0.001)
                {
                    var perp = new Line2d(arc.Center, vec.GetPerpendicularVector());
                    inters = arc.IntersectWith(perp);
                    if (inters == null)
                    {
                        return(null);
                    }
                    vec1      = (inters[0] - arc.Center).GetNormal();
                    i         = vec.X * vec1.Y - vec.Y - vec1.X > 0 ? 0 : 1;
                    j         = i ^ 1;
                    result[i] = new LineSegment2d(inters[0], inters[0] + vec);
                    result[j] = new LineSegment2d(inters[1], inters[1] + vec);
                }
                else
                {
                    var center = arc.Radius < other.Radius ? other.Center : arc.Center;
                    tmp1 = new CircularArc2d(center, Math.Abs(arc.Radius - other.Radius));
                    var tmp2 = new CircularArc2d(arc.Center + vec / 2.0, dist / 2.0);
                    inters = tmp1.IntersectWith(tmp2);
                    if (inters == null)
                    {
                        return(null);
                    }
                    vec1      = (inters[0] - center).GetNormal();
                    vec2      = (inters[1] - center).GetNormal();
                    i         = vec.X * vec1.Y - vec.Y - vec1.X > 0 ? 0 : 1;
                    j         = i ^ 1;
                    result[i] = new LineSegment2d(arc.Center + vec1 * arc.Radius, other.Center + vec1 * other.Radius);
                    result[j] = new LineSegment2d(arc.Center + vec2 * arc.Radius, other.Center + vec2 * other.Radius);
                }
            }

            // inner tangents
            if ((flags & TangentType.Inner) > 0 && !overlap)
            {
                var ratio = arc.Radius / (arc.Radius + other.Radius) / 2.0;
                tmp1   = new CircularArc2d(arc.Center + vec * ratio, dist * ratio);
                inters = arc.IntersectWith(tmp1);
                if (inters == null)
                {
                    return(null);
                }
                vec1      = (inters[0] - arc.Center).GetNormal();
                vec2      = (inters[1] - arc.Center).GetNormal();
                i         = vec.X * vec1.Y - vec.Y - vec1.X > 0 ? 2 : 3;
                j         = i == 2 ? 3 : 2;
                result[i] = new LineSegment2d(arc.Center + vec1 * arc.Radius, other.Center + vec1.Negate() * other.Radius);
                result[j] = new LineSegment2d(arc.Center + vec2 * arc.Radius, other.Center + vec2.Negate() * other.Radius);
            }

            return(result);
        }
Ejemplo n.º 32
0
        public void Slice(DynamicRenderMesh mesh, Camera camera)
        {
            slicePointsDictionary.Clear();
            verticesDictionary.Clear();
            slicePoints.Clear();
            vertices.Clear();
            texCoords.Clear();
            indices.Clear();
            triangles.Clear();
            ResultMeshes.Clear();

            FillVertices(mesh, camera);
            Vector2 A = new Vector2(99999.0f, 99999.0f), B = new Vector2(-99999.0f, -99999.0f);
            var tempLine = new Line2d();
            var workedIndices = new List<int>();
            var tempIndices = new List<int>();
            foreach (var line in Lines)
            {
                for (var i = 0; i < 2; i++)
                {
                    if (line.A[i] < A[i])
                        A[i] = line.A[i];
                    if (line.B[i] > B[i])
                        B[i] = line.B[i];
                }
            }
            for (var i = 0; i < indices.Count / 3; i++)
            {
                var index = i * 3;
                var point0 = vertices[indices[index]];
                var point1 = vertices[indices[index + 1]];
                var point2 = vertices[indices[index + 2]];

                if (!CheckAABB(ref point0, ref point1, ref point2, ref A, ref B))
                {
                    for (var j = 0; j < 3; j++)
                        tempIndices.Add(indices[index + j]);
                    continue;
                }

                for (var j = 0; j < 3; j++)
                    workedIndices.Add(indices[index + j]);
            }

            if (workedIndices.Count == 0)
                return;

            var triangle = new Vector3[3];
            var triangleT = new Vector2[3];
            var tempCollisions = new List<Vector3>();
            var tempTexCoords = new List<Vector2>();
            var tempCollisionsEdgeIndices = new List<int>();
            var newTriangles = new List<int>();
            var info0 = CollisionInfo.Zero;
            var info1 = CollisionInfo.Zero;

            for (var i = 0; i < sliceLines.Count; i++)
            {
                var line = Lines[i];
                var sliceLine = sliceLines[i];
                var trianglesCount = workedIndices.Count / 3;
                for (var j = 0; j < trianglesCount; j++)
                {
                    var index = j * 3;
                    for (var l = 0; l < 3; l++)
                    {
                        triangle[l] = vertices[workedIndices[index + l]];
                        triangleT[l] = texCoords[workedIndices[index + l]];
                    }

                    info0 = CollisionInfo.Zero;
                    info1 = CollisionInfo.Zero;
                    tempCollisions.Clear();
                    tempTexCoords.Clear();
                    tempCollisionsEdgeIndices.Clear();
                    newTriangles.Clear();
                    //looking for a point / intersection point of the triangle and line
                    for (int k = 0, l = 2; k < 3; l = k, k++)
                    {
                        if (info1.Type != CollisionType.CT_NONE)
                            break;
                        var tPoint0 = triangle[l];
                        var tPoint1 = triangle[k];

                        var tTexCoord0 = triangleT[l];
                        var tTexCoord1 = triangleT[k];

                        tempLine.Point0.X = tPoint0.X;
                        tempLine.Point0.Y = tPoint0.Y;
                        tempLine.Point1.X = tPoint1.X;
                        tempLine.Point1.Y = tPoint1.Y;

                        float ua, ub;
                        if (!GetUaUb(tempLine, line, out ua, out ub))
                        {
                            //lines coincide?
                            //Verify whether some point belongs line segment tempLine
                            //if find - get result and break.
                        }
                        else
                        {
                            if (ub < 0.0f || ub > 1.0f)
                                continue;
                            var collisionPoint = tPoint0 + (tPoint1 - tPoint0) * ub;
                            var collisionTexCoord = tTexCoord0 + (tTexCoord1 - tTexCoord0) * ub;
                            if (tempCollisions.Count == 0 || !PointsCompare.Equals(tempCollisions[0], collisionPoint))
                            {
                                tempCollisions.Add(collisionPoint);
                                tempTexCoords.Add(collisionTexCoord);
                                tempCollisionsEdgeIndices.Add(l);
                            }
                            if (ua < 0.0f || ua > 1.0f)
                                continue;

                            var pointType = CollisionType.CT_VERTEX;
                            Vector3 point;
                            Vector2 texCoord;
                            var pointIndex = -1;
                            var edgeIndex = -1;

                            if (ub > 0.0f)
                            {
                                if (ub < 1.0f)
                                {
                                    pointType = CollisionType.CT_EDGE;
                                    point = tempCollisions.Last();
                                    texCoord = tempTexCoords.Last();
                                    edgeIndex = l;
                                }
                                else
                                {
                                    point = tPoint1;
                                    texCoord = tTexCoord1;
                                    pointIndex = workedIndices[index + k];
                                }
                            }
                            else
                            {
                                point = tPoint0;
                                texCoord = tTexCoord0;
                                pointIndex = workedIndices[index + l];
                            }
                            if (info0.Type == CollisionType.CT_NONE)
                            {
                                info0.PointIndex = pointIndex;
                                info0.Type = pointType;
                                info0.Position = point;
                                info0.TexCoord = texCoord;
                                info0.EdgeIndex = edgeIndex;
                            }
                            else
                            {
                                if (pointIndex == -1 || info0.PointIndex != pointIndex)
                                {
                                    info1.PointIndex = pointIndex;
                                    info1.Type = pointType;
                                    info1.Position = point;
                                    info1.TexCoord = texCoord;
                                    info1.EdgeIndex = edgeIndex;
                                }
                            }
                        }
                    }

                    if (info1.Type == CollisionType.CT_NONE)
                    {
                        if (tempCollisions.Count == 0)
                        {
                            if (info0.Type == CollisionType.CT_NONE)
                                continue;
                        }
                        else
                        {
                            if (tempCollisions.Count > 1)
                            {
                                //Perhaps the point inside the triangle
                                var dir = line.Direction;
                                for (var l = 0; l < 2; l++)
                                {
                                    var p = l == 0 ? line.Point0 : line.Point1;
                                    if (PointInTriangle(ref triangle[0], ref triangle[1], ref triangle[2], ref p))
                                    {
                                        var v0 = tempCollisions[1].Xy - tempCollisions[0].Xy;
                                        var v1 = p - tempCollisions[0].Xy;
                                        var k = (v1.Length / v0.Length);
                                        var z = tempCollisions[0].Z + (tempCollisions[1].Z - tempCollisions[0].Z) * k;
                                        var t = tempTexCoords[0] + (tempTexCoords[1] - tempTexCoords[0]) * k;
                                        if (info0.Type == CollisionType.CT_NONE)
                                        {
                                            info0.Type = CollisionType.CT_INSIDE;
                                            info0.Position = new Vector3(p.X, p.Y, z);
                                            info0.TexCoord = t;
                                            if (Vector2.Dot(dir, v0) > 0.0f)
                                                info0.EdgeIndex = tempCollisionsEdgeIndices[0];
                                            else
                                                info0.EdgeIndex = tempCollisionsEdgeIndices[1];
                                            tempCollisionsEdgeIndices.Remove(info0.EdgeIndex);
                                        }
                                        else
                                        {
                                            info1.Type = CollisionType.CT_INSIDE;
                                            info1.Position = new Vector3(p.X, p.Y, z);
                                            info1.TexCoord = t;
                                            info1.EdgeIndex = tempCollisionsEdgeIndices[0];
                                        }
                                    }
                                }
                            }
                        }
                    }

                    if (info0.Type == CollisionType.CT_NONE)
                        continue;
                    //Create new triangles, if we have two points of intersection, and they are not vertices
                    int pi1 = 0, pi0 = 0;
                    if (info1.Type != CollisionType.CT_NONE && (info0.Type != CollisionType.CT_VERTEX || info1.Type != CollisionType.CT_VERTEX ))
                    {
                        if (info1.Type == CollisionType.CT_VERTEX
                            || (info1.Type == CollisionType.CT_EDGE && info0.Type == CollisionType.CT_INSIDE)
                            || (info1.Type == CollisionType.CT_EDGE && info0.Type == CollisionType.CT_EDGE && (info0.EdgeIndex + 1) % 3 != info1.EdgeIndex)
                            || (info0.Type == CollisionType.CT_INSIDE && info1.Type == CollisionType.CT_INSIDE && (info0.EdgeIndex + 1) % 3 != info1.EdgeIndex))
                        {
                            var temp = info1;
                            info1 = info0;
                            info0 = temp;
                        }

                        if (!verticesDictionary.TryGetValue(info1.Position, out pi1))
                        {
                            pi1 = vertices.Count;
                            vertices.Add(info1.Position);
                            texCoords.Add(info1.TexCoord);
                            verticesDictionary.Add(info1.Position, pi1);
                        }

                        if (info0.Type == CollisionType.CT_VERTEX) //One point of intersection coincides with the vertex
                        {
                            pi0 = info0.PointIndex;
                            int i0 = workedIndices[index], i1 = workedIndices[index + 1], i2 = workedIndices[index + 2];
                            if (i0 == info0.PointIndex)
                            {
                                i0 = i2;
                                i2 = i1;
                            }
                            else
                            {
                                if (i2 == info0.PointIndex)
                                {
                                    i2 = i0;
                                    i0 = i1;
                                }
                            }
                            i1 = info0.PointIndex;

                            newTriangles.AddRange(new[] {   i0, i1, pi1,
                                                            i1, i2, pi1 });
                            if (info1.Type == CollisionType.CT_INSIDE) //The second point inside the triangle
                                newTriangles.AddRange(new[] { i2, i0, pi1 });
                        }
                        else
                        {
                            if (!verticesDictionary.TryGetValue(info0.Position, out pi0))
                            {
                                pi0 = vertices.Count;
                                vertices.Add(info0.Position);
                                texCoords.Add(info0.TexCoord);
                                verticesDictionary.Add(info0.Position, pi0);
                            }

                            if (info1.Type != info0.Type) //One point crosses the brink, the second inside the triangle
                            {
                                var prev = info0.EdgeIndex == 0 ? 2 : info0.EdgeIndex - 1;
                                prev = workedIndices[index + prev];
                                var next = info0.EdgeIndex == 2 ? 0 : info0.EdgeIndex + 1;
                                next = workedIndices[index + next];
                                var curr = workedIndices[index + info0.EdgeIndex];
                                newTriangles.AddRange(new[] {   prev, curr, pi1,
                                                                curr, pi0, pi1,
                                                                pi0, next, pi1,
                                                                next, prev, pi1 });
                            }
                            else
                            {
                                var c0 = workedIndices[index + info0.EdgeIndex];
                                var c1 = workedIndices[index + info1.EdgeIndex];
                                var c2 = workedIndices[index + ((info1.EdgeIndex + 1) % 3)];

                                if (info0.Type == CollisionType.CT_EDGE)
                                {
                                    newTriangles.AddRange(new[] {   c0, pi0, pi1,
                                                                pi0, c1, pi1,
                                                                pi1, c2, c0 });
                                }
                                else
                                {
                                    newTriangles.AddRange(new[] {   c0, c1, pi0,
                                                                    c1, pi1, pi0,
                                                                    c1, c2, pi1,
                                                                    c2, c0, pi1,
                                                                    c0, pi0, pi1});

                                }
                            }
                        }
                    }
                    int slicePointIndex;
                    SlicePoint slicePoint;
                    for (var l = 0; l < 2; l++)
                    {
                        if (l == 1 && info1.Type == CollisionType.CT_NONE)
                            break;
                        var position = l == 0 ? info0.Position.Xy : info1.Position.Xy;
                        var pointIndex = l == 0 ? pi0 : pi1;
                        if (!slicePointsDictionary.TryGetValue(position, out slicePointIndex))
                        {
                            slicePoint = new SlicePoint
                            {
                                Coordinate = position
                            };
                            slicePoint.Lines.Add(sliceLine);
                            slicePoint.PreparePoint();
                            slicePointIndex = slicePoints.Count;
                            slicePoints.Add(slicePoint);
                            slicePointsDictionary.Add(position, slicePointIndex);
                        }
                        else
                            slicePoint = slicePoints[slicePointIndex];
                        if (!slicePoint.Indices.Contains(pointIndex))
                            slicePoint.Indices.Add(pointIndex);
                    }

                    if (newTriangles.Count > 0)
                    {
                        for (var l = 0; l < 3; l++)
                            workedIndices[index + l] = newTriangles[l];
                        newTriangles.RemoveRange(0, 3);
                        workedIndices.InsertRange(index, newTriangles);
                        var count = (newTriangles.Count / 3);
                        j += count;
                        trianglesCount += count;
                    }
                }
            }

            for (var i = 0; i < workedIndices.Count / 3; i++)
            {
                var index = i * 3;
                var t = new Triangle();
                for (var j = 0; j < 3; j++)
                    t.Indices[j] = workedIndices[index + j];
                triangles.Add(i, new TrianleConnections
                {
                    Triangle = t
                });
            }

            var ind = new List<int>();
            var tempTriangle = new Triangle();
            tempTriangle.Indices[1] = -1;
            foreach (var point in slicePoints)
            {
                point.PreparePoint();
                foreach (var index in point.Indices)
                {
                    ind.Clear();
                    ind.Add(index);
                    tempTriangle.Indices[0] = index;
                    //Duplicate the verticle several times
                    for (var i = 1; i < point.Directions.Count; i++)
                    {
                        ind.Add(vertices.Count);
                        vertices.Add(vertices[index]);
                        texCoords.Add(texCoords[index]);
                    }
                    foreach (var t in triangles)
                    {
                        var tr = t.Value.Triangle;
                        var id = Triangle.TriangleEquals(ref tempTriangle, ref tr);
                        if (id > -1)
                        {
                            var center = (vertices[tr.Indices[0]].Xy + vertices[tr.Indices[1]].Xy + vertices[tr.Indices[2]].Xy) / 3.0f;
                            var dir = (center - point.Coordinate).Normalized();
                            var angle = SlicePoint.GetAngle(ref dir);
                            var ii = point.Directions.Count - 1;
                            for (var j = 0; j < point.Directions.Count; j++)
                            {
                                if (angle < point.Directions[j])
                                    break;
                                ii = j;
                            }
                            tr.Indices[id] = ind[ii];
                        }
                    }
                }
            }

            var invTransform = mesh.Transform * camera.ViewMatrix;
            invTransform.Invert();
            for (var i = 0; i < vertices.Count; i++)
            {
                vertices[i] = Vector3.Transform(vertices[i], invTransform);
            }

            workedIndices.Clear();

            foreach (var t in triangles)
            {
                foreach (var i in t.Value.Triangle.Indices)
                    workedIndices.Add(i);
            }
            workedIndices.AddRange(tempIndices);
            triangleConnections.Clear();
            triangles.Clear();

            for (var i = 0; i < workedIndices.Count / 3; i++)
            {
                var index = i * 3;
                var t = new Triangle();
                for (var j = 0; j < 3; j++)
                {
                    t.Indices[j] = workedIndices[index + j];
                    List<int> l;
                    if (!triangleConnections.TryGetValue(t.Indices[j], out l))
                    {
                        l = new List<int>();
                        triangleConnections.Add(t.Indices[j], l);
                    }
                    l.Add(i);
                }
                triangles.Add(i, new TrianleConnections
                {
                    Triangle = t
                });
            }

            var mainMesh = true;
            while (triangles.Count > 0)
            {
                foundedTriangles.Clear();
                FillTriangles(triangles.First().Key);

                if (mainMesh)
                {
                    mesh.Create(vertices, texCoords, foundedTriangles, mesh.Material.DiffuseTextureMap, mesh.Material.TransparentTextureMap, mesh.TextureAngle, mesh.TextureSize);
                    mainMesh = false;
                }
                else
                {
                    var tmpMesh = new DynamicRenderMesh(MeshType.Hair);
                    tmpMesh.Create(vertices, texCoords, foundedTriangles, mesh.Material.DiffuseTextureMap, mesh.Material.TransparentTextureMap, mesh.TextureAngle, mesh.TextureSize);
                    tmpMesh.Transform = mesh.Transform;
                    tmpMesh.Material.DiffuseColor = mesh.Material.DiffuseColor;
                    tmpMesh.MeshAngle = mesh.MeshAngle;
                    tmpMesh.MeshSize = mesh.MeshSize;

                    var info = tmpMesh.GetMeshInfo(1.0f);
                    var center = Vector3.Zero;
                    var scale = PickingController.GetHairScale(ProgramCore.Project.ManType);
                    foreach (var vert in info.Positions)
                    {
                        center.X += vert.X * scale;
                        center.Y += vert.Y * scale;
                        center.Z += vert.Z * scale;
                    }
                    center /= info.Positions.Count;
                    tmpMesh.Position = center;

                    ResultMeshes.Add(tmpMesh);
                }
            }
        }
Ejemplo n.º 33
0
        /// <summary>
        /// Returns the tangents between the active CircularArc2d instance complete circle and another one.
        /// </summary>
        /// <remarks>
        /// Tangents start points are on the object to which this method applies, end points on the one passed as argument.
        /// Tangents are always returned in the same order: outer tangents before inner tangents, and for both,
        /// the tangent on the left side of the line from this circular arc center to the other one before the other one.
        /// </remarks>
        /// <param name="arc">The instance to which this method applies.</param>
        /// <param name="other">The CircularArc2d to which searched for tangents.</param>
        /// <param name="flags">An enum value specifying which type of tangent is returned.</param>
        /// <returns>An array of LineSegment2d representing the tangents (maybe 2 or 4) or null if there is none.</returns>
        public static LineSegment2d[] GetTangentsTo(this CircularArc2d arc, CircularArc2d other, TangentType flags)
        {
            // check if a circle is inside the other
            double dist = arc.Center.GetDistanceTo(other.Center);
            if (dist - Math.Abs(arc.Radius - other.Radius) <= Tolerance.Global.EqualPoint)
                return null;

            // check if circles overlap
            bool overlap = arc.Radius + other.Radius >= dist;
            if (overlap && flags == TangentType.Inner)
                return null;

            CircularArc2d tmp1, tmp2;
            Point2d[] inters;
            Vector2d vec1, vec2, vec = other.Center - arc.Center;
            int i, j;
            LineSegment2d[] result = new LineSegment2d[(int)flags == 3 && !overlap ? 4 : 2];

            // outer tangents
            if ((flags & TangentType.Outer) > 0)
            {
                if (arc.Radius == other.Radius)
                {
                    Line2d perp = new Line2d(arc.Center, vec.GetPerpendicularVector());
                    inters = arc.IntersectWith(perp);
                    if (inters == null)
                        return null;
                    vec1 = (inters[0] - arc.Center).GetNormal();
                    vec2 = (inters[1] - arc.Center).GetNormal();
                    i = vec.X * vec1.Y - vec.Y - vec1.X > 0 ? 0 : 1;
                    j = i ^ 1;
                    result[i] = new LineSegment2d(inters[0], inters[0] + vec);
                    result[j] = new LineSegment2d(inters[1], inters[1] + vec);
                }
                else
                {
                    Point2d center = arc.Radius < other.Radius ? other.Center : arc.Center;
                    tmp1 = new CircularArc2d(center, Math.Abs(arc.Radius - other.Radius));
                    tmp2 = new CircularArc2d(arc.Center + vec / 2.0, dist / 2.0);
                    inters = tmp1.IntersectWith(tmp2);
                    if (inters == null)
                        return null;
                    vec1 = (inters[0] - center).GetNormal();
                    vec2 = (inters[1] - center).GetNormal();
                    i = vec.X * vec1.Y - vec.Y - vec1.X > 0 ? 0 : 1;
                    j = i ^ 1;
                    result[i] = new LineSegment2d(arc.Center + vec1 * arc.Radius, other.Center + vec1 * other.Radius);
                    result[j] = new LineSegment2d(arc.Center + vec2 * arc.Radius, other.Center + vec2 * other.Radius);
                }
            }

            // inner tangents
            if ((flags & TangentType.Inner) > 0 && !overlap)
            {
                double ratio = (arc.Radius / (arc.Radius + other.Radius)) / 2.0;
                tmp1 = new CircularArc2d(arc.Center + vec * ratio, dist * ratio);
                inters = arc.IntersectWith(tmp1);
                if (inters == null)
                    return null;
                vec1 = (inters[0] - arc.Center).GetNormal();
                vec2 = (inters[1] - arc.Center).GetNormal();
                i = vec.X * vec1.Y - vec.Y - vec1.X > 0 ? 2 : 3;
                j = i == 2 ? 3 : 2;
                result[i] = new LineSegment2d(arc.Center + vec1 * arc.Radius, other.Center + vec1.Negate() * other.Radius);
                result[j] = new LineSegment2d(arc.Center + vec2 * arc.Radius, other.Center + vec2.Negate() * other.Radius);
            }
            return result;
        }
Ejemplo n.º 34
0
 public void Add(Line2d e)
 {
     Lines2d.Add(e);
 }
Ejemplo n.º 35
0
        private bool GetUaUb(Line2d line1, Line2d line2, out float ua, out float ub)
        {
            ua = 0.0f;
            ub = 0.0f;
            // denominator
            var a = line1.Point1.Y - line1.Point0.Y;
            var d = line1.Point1.X - line1.Point0.X;
            var b = line2.Point0.X - line2.Point1.X;
            var c = line2.Point0.Y - line2.Point1.Y;
            var e = line2.Point0.X - line1.Point0.X;
            var f = line2.Point0.Y - line1.Point0.Y;

            var z = a * b - c * d;
            // numerator 1
            var ca = a * e - f * d;
            // numerator 2
            var cb = f * b - c * e;
            if (z == 0.0f)
                return false;

            ua = ca / z;
            ub = cb / z;
            return true;
        }
Ejemplo n.º 36
0
 // The point of intersection of two segments
 private bool CollisionSegments(Line2d line1, Line2d line2, out Vector2 point)
 {
     point = Vector2.Zero;
     float ua, ub;
     if (!GetUaUb(line1, line2, out ua, out ub))
         return false;
     if ((0.0f < ua) && (ua < 1.0f) && (0.0f < ub) && (ub < 1.0f))
     {
         point.X = line1.Point0.X + (line1.Point1.X - line1.Point0.X) * ub;
         point.Y = line1.Point0.Y + (line1.Point1.Y - line1.Point0.Y) * ub;
         return true;
     }
     return false;
 }
Ejemplo n.º 37
0
 public void Remove(Line2d e)
 {
     Lines2d.Remove(e);
 }