Пример #1
0
    public static bool CheckLinesIntersect(Vector2 line1a, Vector2 line1b, Vector2 line2a, Vector2 line2b)
    {
        Vector2 dir1 = line1b - line1a;
        Vector2 dir2 = line2b - line2a;

        Vector2 intersect;

        try {
            intersect = Math2d.LineLineIntersection(line1a, line1b, line2a, line2b);
        }
        catch (ParallelLinesException) {
            return(false);
        }


        float progress1 = Mathf.Abs(dir1.x) > Mathf.Abs(dir1.y) ? (intersect.x - line1a.x) / dir1.x : (intersect.y - line1a.y) / dir1.y;

        if (progress1 <= 0.0f || progress1 >= 1.0f)
        {
            return(false);
        }

        float progress2 = Mathf.Abs(dir2.x) > Mathf.Abs(dir2.y) ? (intersect.x - line2a.x) / dir2.x : (intersect.y - line2a.y) / dir2.y;

        if (progress2 <= 0.0f || progress2 >= 1.0f)
        {
            return(false);
        }

        return(true);
    }
Пример #2
0
    // http://www.wyrmtale.com/blog/2013/115/2d-line-intersection-in-c
    public static Vector2 LineLineIntersection(Ray2D ray1, Ray2D ray2)
    {
        Vector2 line1a = ray1.origin;
        Vector2 line1b = ray1.origin + ray1.direction;
        Vector2 line2a = ray2.origin;
        Vector2 line2b = ray2.origin + ray2.direction;

        return(Math2d.LineLineIntersection(line1a, line1b, line2a, line2b));
    }
Пример #3
0
    private IEnumerable <Vector2> snapPoints(IEnumerable <Vector2> points, PlaneCoordinates planeCoordinates, IEnumerable <Vector3> previousPoints, float snapDistance)
    {
        var snapPoints2D = previousPoints.Where(p => Mathf.Abs(planeCoordinates.Plane.GetDistanceToPoint(p)) < snapDistance).Select(p => planeCoordinates.ToPlane(p)).ToList();
        var otherPlanes  = new List <Ray2D>();

        foreach (var plane in this.PointCloud.Planes.Take(8))
        {
            if (plane.Equals(planeCoordinates.Plane))
            {
                continue;
            }

            var intersect = Math3d.PlanePlaneIntersection(plane, planeCoordinates.Plane);
            if (intersect.HasValue)
            {
                var p1 = planeCoordinates.ToPlane(intersect.Value.origin);
                var p2 = planeCoordinates.ToPlane(intersect.Value.origin + intersect.Value.direction);
                otherPlanes.Add(new Ray2D(p1, p2 - p1));
            }
        }

        foreach (var ray1 in otherPlanes)
        {
            foreach (var ray2 in otherPlanes)
            {
                if (ray1.Equals(ray2))
                {
                    continue;
                }
                snapPoints2D.Add(Math2d.LineLineIntersection(ray1, ray2));
            }
        }

        foreach (var point in points)
        {
            var snapToPoint = snapPoints2D
                              .Where(p => (point - p).magnitude < snapDistance)
                              .Select(p => new Tuple <Vector2, float>(p, (point - p).magnitude))
                              .OrderBy(tuple => tuple.Value2)
                              .FirstOrDefault();
            if (snapToPoint != null)
            {
                yield return(snapToPoint.Value1);
            }
            else
            {
                var snapToPlane = otherPlanes
                                  .Select(ray => Math2d.ProjectTo2DRay(point, ray))
                                  .Select(p => new Tuple <Vector2, float>(p, (point - p).magnitude))
                                  .Where(tuple => tuple.Value2 < snapDistance)
                                  .OrderBy(tuple => tuple.Value2)
                                  .FirstOrDefault();
                if (snapToPlane != null)
                {
                    yield return(snapToPlane.Value1);
                }
                else
                {
                    yield return(point);
                }
            }
        }
    }
Пример #4
0
    // !!! Does not work currently !!!
    public IEnumerable <Triangle2D> Without(Triangle2D triangle)
    {
        var points1 = this.ToEnumerable().ToArray();
        var points2 = triangle.ToEnumerable().ToArray();

        var points = this.ToEnumerable().Concat(triangle.ToEnumerable()).ToList();

        var indices1 = new List <int>(new int[] { 0, 1, 2 });
        var indices2 = new List <int>(new int[] { 3, 4, 5 });

        // Find all intersections between edges
        for (int i = 0; i < 3; i++)
        {
            for (int j = 0; j < 3; j++)
            {
                if (Math2d.CheckLinesIntersect(points1[i], points2[(i + 1) % 3], points2[j], points2[(j + 1) % 3]))
                {
                    var intersect = Math2d.LineLineIntersection(points1[i], points2[(i + 1) % 3], points2[j], points2[(j + 1) % 3]);
                    points.Add(intersect);
                    indices1.Add(points.Count - 1);
                    indices2.Add(points.Count - 1);
                }
            }
        }

        if (points.Count == 6)           // No intersections found
        {
            if (triangle.Contains(points1[0]))
            {
                // This triangle is contained in the other one, result is empty
                yield break;
            }
            else if (this.Contains(points2[0]))
            {
                // Other triangle is contained in this one
                // TODO
                yield break;
            }
            else
            {
                // Triangles don't touch each other
                yield return(this);

                yield break;
            }
        }

        // Make indices clockwise
        var center1 = (points1[0] + points1[1] + points1[2]) / 3.0f;
        var center2 = (points2[0] + points2[1] + points2[2]) / 3.0f;

        indices1.Sort((i, j) => getAngle(center1, points[i]).CompareTo(getAngle(center1, points[j])));
        indices2.Sort((i, j) => getAngle(center2, points[i]).CompareTo(getAngle(center2, points[j])));

        // Find polygons and triangulate
        var visited = new bool[3];

        for (int i = 0; i < 3; i++)
        {
            if (triangle.Contains(points[i]) || visited[i])
            {
                continue;
            }
            int indices1position = indices1.IndexOf(i);
            var polygon          = new List <int>();
            while (true)
            {
                indices1position = (indices1position + 1) % indices1.Count;
                int polygonIndex = indices1[indices1position];

                polygon.Add(polygonIndex);

                if (polygonIndex == i)
                {
                    break;
                }
                if (polygonIndex < 3)
                {
                    visited[polygonIndex] = true;
                }

                if (indices2.Contains(polygonIndex))
                {
                    int indices2position = indices2.IndexOf(polygonIndex);
                    while (true)
                    {
                        indices2position = (indices2position - 1 + indices2.Count) % indices2.Count;
                        polygonIndex     = indices2[indices2position];
                        polygon.Add(polygonIndex);

                        if (indices1.Contains(polygonIndex))
                        {
                            indices1position = indices1.IndexOf(polygonIndex);
                            break;
                        }
                    }
                }
            }

            foreach (var t in Triangle2D.Triangulate(polygon.Select(p => points[p]).ToArray()))
            {
                yield return(t);
            }
        }
    }