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); }
// 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)); }
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); } } } }
// !!! 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); } } }