public bool RayIntersect(Ray2DD l2, out Vector2D res) { LineSegment2D l1 = this; bool b = RayIntersect(l1.first.x, l1.first.y, l1.second.x, l1.second.y, l2.origin.x, l2.origin.y, l2.origin.x + l2.direction.x * 1000000, l2.origin.y + l2.direction.y * 1000000, out res); if (b) { return((first - res).magnitude + (second - res).magnitude <= (first - second).magnitude + 0.0001f);; } return(false); }
// if the line segment is inside or is intersecting with the triangle then cut // otherwise return this as an array public Triangle2D[] Cut(LineSegment2D line, double minDist = 0.1f) { if (IsPointInside(line.first) || IsPointInside(line.second) || IsIntersecting(line)) { Ray2DD ray = new Ray2DD(line.first, line.second - line.first); Vector2D[] collisions = new Vector2D[3]; LineSegment2D[] segments = GetLineSegments(); bool[] inside = { IsPointInside(line.first), IsPointInside(line.second) }; bool onlyOnePointInside = inside [0] ^ inside [1]; if (onlyOnePointInside) { Vector2D newPoint = new Vector2D(); for (int i = 0; i < segments.Length; i++) { if (segments[i].LineIntersect(line, out newPoint)) { // if minimum distance is too small return this if (Vector2D.Distance(newPoint, points [i]) < minDist || Vector2D.Distance(newPoint, points [(i + 1 + 3) % 3]) < minDist) { return(new Triangle2D[] { this }); } return(new Triangle2D[] { new Triangle2D(points[i], newPoint, points[(i - 1 + 3) % 3]), new Triangle2D(newPoint, points[(i + 1 + 3) % 3], points[(i + 2 + 3) % 3]) }); } } } bool[] intersection = new bool[3]; double[] minDistPerCollision = new double[3]; int minDisCount = 0; for (int i = 0; i < 3; i++) { intersection [i] = segments [i].RayIntersect(ray, out collisions [i]); if (!intersection[i]) { minDistPerCollision[i] = double.MaxValue; } else { minDistPerCollision [i] = System.Math.Min(Vector2D.Distance(segments [i].first, collisions [i]), Vector2D.Distance(segments [i].second, collisions [i])); if (minDistPerCollision [i] < minDist) { minDisCount++; } } } int collisionCount = 0; foreach (var i in intersection) { if (i) { collisionCount++; } } if (collisionCount != 2 || minDisCount >= 2) { return(new Triangle2D[] { this }); } if (minDisCount == 1) { for (int i = 0; i < 3; i++) { if (intersection [i] && minDistPerCollision [i] >= minDist) { return(new Triangle2D[] { new Triangle2D(points[i], collisions[i], points[(i - 1 + 3) % 3]), new Triangle2D(points[(i + 1) % 3], points[(i + 2) % 3], collisions[i]) }); } } } int cutOffCorner = intersection[2] == false?1:(intersection[1] == false?0:2); return(new Triangle2D[] { new Triangle2D(points[cutOffCorner], collisions[cutOffCorner], collisions[(cutOffCorner - 1 + 3) % 3]), new Triangle2D(collisions[cutOffCorner], points[(cutOffCorner + 1) % 3], collisions[(cutOffCorner - 1 + 3) % 3]), new Triangle2D(points[(cutOffCorner + 1) % 3], points[(cutOffCorner + 2) % 3], collisions[(cutOffCorner - 1 + 3) % 3]), }); } else { return(new Triangle2D[] { this }); } }
public bool RayIntersect(Ray2DD l2, out Vector2D res) { LineSegment2D l1 = this; bool b = RayIntersect(l1.first.x, l1.first.y, l1.second.x, l1.second.y, l2.origin.x, l2.origin.y, l2.origin.x + l2.direction.x*1000000, l2.origin.y + l2.direction.y*1000000, out res); if (b){ return (first - res).magnitude + (second - res).magnitude <= (first - second).magnitude + 0.0001f;; } return false; }
// if the line segment is inside or is intersecting with the triangle then cut // otherwise return this as an array public Triangle2D[] Cut(LineSegment2D line, double minDist = 0.1f) { if (IsPointInside (line.first) || IsPointInside (line.second) || IsIntersecting (line)) { Ray2DD ray = new Ray2DD (line.first, line.second - line.first); Vector2D[] collisions = new Vector2D[3]; LineSegment2D[] segments = GetLineSegments (); bool[] inside = { IsPointInside(line.first), IsPointInside(line.second) }; bool onlyOnePointInside = inside [0] ^ inside [1]; if (onlyOnePointInside) { Vector2D newPoint = new Vector2D (); for (int i = 0; i < segments.Length; i++) { if (segments[i].LineIntersect(line, out newPoint)) { // if minimum distance is too small return this if (Vector2D.Distance (newPoint, points [i]) < minDist || Vector2D.Distance (newPoint, points [(i + 1 + 3) % 3]) < minDist) { return new Triangle2D[]{ this }; } return new Triangle2D[]{ new Triangle2D(points[i], newPoint,points[(i-1+3)%3]), new Triangle2D(newPoint,points[(i+1+3)%3],points[(i+2+3)%3]) }; } } } bool[] intersection = new bool[3]; double[] minDistPerCollision = new double[3]; int minDisCount = 0; for (int i = 0; i < 3; i++) { intersection [i] = segments [i].RayIntersect (ray, out collisions [i]); if (!intersection[i]) { minDistPerCollision[i] = double.MaxValue; } else { minDistPerCollision [i] = System.Math.Min (Vector2D.Distance (segments [i].first, collisions [i]), Vector2D.Distance (segments [i].second, collisions [i])); if (minDistPerCollision [i] < minDist) { minDisCount++; } } } int collisionCount = 0; foreach (var i in intersection) { if (i) { collisionCount++; } } if (collisionCount != 2 || minDisCount>=2) { return new Triangle2D[]{ this}; } if (minDisCount == 1) { for (int i = 0; i < 3; i++) { if (intersection [i] && minDistPerCollision [i] >= minDist) { return new Triangle2D[]{ new Triangle2D(points[i], collisions[i],points[(i-1+3)%3]), new Triangle2D(points[(i+1)%3],points[(i+2)%3],collisions[i]) }; } } } int cutOffCorner = intersection[2]==false?1:(intersection[1]==false?0:2); return new Triangle2D[]{ new Triangle2D(points[cutOffCorner], collisions[cutOffCorner],collisions[(cutOffCorner-1+3)%3]), new Triangle2D(collisions[cutOffCorner],points[(cutOffCorner+1)%3],collisions[(cutOffCorner-1+3)%3]), new Triangle2D(points[(cutOffCorner+1)%3],points[(cutOffCorner+2)%3],collisions[(cutOffCorner-1+3)%3]), }; } else { return new Triangle2D[]{this}; } }