public static bool getIntersection(LineSegment2D line, double x1, double y1, double x2, double y2, out Vector2D res) { res = Vector2D.zero; double denom = ((line.second.y - line.first.y) * (x2 - x1)) - ((line.second.x - line.first.x) * (y2 - y1)); double nume_a = ((line.second.x - line.first.x) * (y1 - line.first.y)) - ((line.second.y - line.first.y) * (x1 - line.first.x)); double nume_b = ((x2 - x1) * (y1 - line.first.y)) - ((y2 - y1) * (x1 - line.first.x)); if (denom == 0.0f) { return false; } double ua = nume_a / denom; double ub = nume_b / denom; if ((ua >= 0.0f) && (ua <= 1.0f) && (ub >= 0.0f) && (ub <= 1.0f)) { // Get the intersection point. double intersectX = (line.first.x + ua * (line.second.x - line.first.x)); double intersectY = (line.first.y + ua * (line.second.y - line.first.y)); res = new Vector2D(intersectX, intersectY); return true; } return false; }
public static bool doesIntersect(LineSegment2D ln1, LineSegment2D ln2) { double denom = ((ln2.second.y - ln2.first.y) * (ln1.second.x - ln1.first.x)) - ((ln2.second.x - ln2.first.x) * (ln1.second.y - ln1.first.y)); if (denom == 0.0) { return false; } double ua = ((ln2.second.x - ln2.first.x) * (ln1.first.y - ln2.first.y)) - ((ln2.second.y - ln2.first.y) * (ln1.first.x - ln2.first.x)) / denom; double ub = ((ln1.second.x - ln1.first.x) * (ln1.first.y - ln2.first.y)) - ((ln1.second.y - ln1.first.y) * (ln1.first.x - ln2.first.x)) / denom; return ((ua >= 0.0f) && (ua <= 1.0f) && (ub >= 0.0f) && (ub <= 1.0f)); }
public bool IsPointInside(Vector2D point) { Vector2D[] farFarAwayPoints = new Vector2D[]{ point+new Vector2(99999,99998), point+new Vector2(-99999,89990), }; LineSegment2D[] lineSegments = new LineSegment2D[]{ new LineSegment2D(point, farFarAwayPoints[0]), new LineSegment2D(point, farFarAwayPoints[1]), }; foreach (var ls in lineSegments) { int hits = 0; for (int i=0;i<3;i++){ LineSegment2D l1 = new LineSegment2D(Polygon.V2(points[i]), Polygon.V2(points[(i+1)%3])); Vector2D res = Vector2D.zero; if (ls.LineIntersect(l1,out res)){ hits++; } } if (hits%2==1){ return true; } } return false; }
public bool IsIntersecting(LineSegment2D ls) { foreach (var l in GetLineSegments()){ Vector2D p = new Vector2D (); if (ls.LineIntersect(l, out p)) { return true; } } return false; }
public LineSegment2D[] GetLineSegments() { LineSegment2D[] res = new LineSegment2D[3]; for (int i=0;i<3;i++){ res[i] = new LineSegment2D(new Vector2D(points[i].x,points[i].z), new Vector2D(points[(i+1)%3].x,points[(i+1)%3].z)); } return res; }
// if the line segment is inside or is intersecting with the triangle then cut // otherwise return this as an array public Triangle[] Cut(LineSegment2D line) { if (IsPointInside (line.first) || IsPointInside (line.second) || IsIntersecting (line)) { return new Triangle[]{ this }; } else { return new Triangle[]{ this}; } }
public bool LineIntersect(LineSegment2D l2, out Vector2D res) { LineSegment2D l1 = this; return LineIntersect(l1.first.x, l1.first.y, l1.second.x, l1.second.y, l2.first.x, l2.first.y, l2.second.x, l2.second.y, out res); }
private Quad2D CreateQuadFromLineSegment (LineSegment2D ls, float TailLen, float HeadLen) { float pitch = ls.Pitch (); Quad2D ret = new Quad2D (); float theta = pitch; ret.a = new TVector2(TailLen * Mathf.Sin(theta) + ls.a.Value.x, -TailLen * Mathf.Cos(theta) + ls.a.Value.y, ls.a.Tag); ret.d = new TVector2(-TailLen * Mathf.Sin(theta) + ls.a.Value.x, TailLen * Mathf.Cos(theta) + ls.a.Value.y, ls.a.Tag); ret.b = new TVector2(HeadLen * Mathf.Sin(theta) + ls.b.Value.x, -HeadLen * Mathf.Cos(theta) + ls.b.Value.y, ls.b.Tag); ret.c = new TVector2(-HeadLen * Mathf.Sin(theta) + ls.b.Value.x, HeadLen * Mathf.Cos(theta) + ls.b.Value.y, ls.b.Tag); return ret; }
public Triangle3[] GetStraightSpokePlane (TVector3 origin, float zOffset, string Tag1, string Tag2) { System.Collections.Generic.List<Triangle3> tris = new List<Triangle3> (); //Calc the angle to sweep... float inctheta = 2 * Mathf.PI / ((float)_spokeCount); float theta = 0.0f; float adjAngle = 0.0f; System.Collections.Generic.List<LineSegment2D> spokelines = new System.Collections.Generic.List<LineSegment2D> (); for (int i = 0; i < (_spokeCount + 1); i++) { adjAngle = inctheta; TVector2 pt1; TVector2 pt2; if(_hubRadius !=0){ pt1 = new TVector2((_hubRadius) * Mathf.Cos(theta) + origin.Value.x, (_hubRadius) * Mathf.Sin(theta) + origin.Value.y, VERT_SpokeEdgeTop); }else{ pt1 = new TVector2(origin.Value.x, origin.Value.y, VERT_SpokeEdgeTop); } pt2 = new TVector2(_ringRadius * Mathf.Cos(theta) + origin.Value.x, _ringRadius * Mathf.Sin(theta) + origin.Value.y, VERT_SpokeEdgeTop); LineSegment2D ls = new LineSegment2D (); ls.a = pt1; ls.b = pt2; spokelines.Add (ls); theta += (adjAngle); } theta = 0.0f; for (int i = 0; i < (_spokeCount); i++) { Quad3D q3; var q2 = CreateQuadFromLineSegment (spokelines [i], _spokeWidthInner, _spokeWidthOuter); q3 = new Quad3D().Create(q2, origin.Value.z); q3.Tag = Tag1; var qtris = q3.GetTris (); qtris[0].Tag = q3.Tag; qtris[0].SortOrder = _triOrder; _triOrder += 2; qtris[1].Tag = Tag2; qtris[1].SortOrder = _triOrder; _triOrder += 2; tris.AddRange (qtris); } return tris.ToArray (); }
public List<HitInfo> IntersectTriangle(Triangle triangle) { List<HitInfo> res = new List<HitInfo>(); for (int i=0;i<vertices.Count;i++){ LineSegment2D l1 = new LineSegment2D(V2(vertices[i]), V2(vertices[(i+1)%vertices.Count])); for (int j=0;j<3;j++){ LineSegment2D l2 = new LineSegment2D(V2(triangle.Vertex(j)), V2(triangle.Vertex((j+1)%3))); Vector2D point; if (l1.LineIntersect(l2, out point)){ double distance = (point - V2(vertices[i])).magnitude; double segmentLength = l1.Length(); //if (l1.DoLinesIntersect(l2)){ double normalizedDistance = distance/segmentLength; Vector3D point3D = Vector3D.Lerp (new Vector3D (vertices[i]), new Vector3D (vertices[(i+1)%vertices.Count]), normalizedDistance); res.Add(new HitInfo(i,j,point3D.ToVector3())); } /*Vector2 intersectionPoint; if (LineLineIntersection(from,to, tFrom, tTo,out intersectionPoint)){ float normalizedDistance = Vector3.Dot(to-from, tTo-tFrom); Vector3 point3D = Vector3.Lerp (vertices[i], vertices[(i+1)%vertices.Count], normalizedDistance); res.Add(new HitInfo(i,j,point3D)); }*/ } } return res; }
// 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 IsIntersecting(LineSegment2D ls, out Vector2D p) { foreach (var l in GetLineSegments()){ if (ls.LineIntersect(l, out p)) { return true; } } p = Vector2D.zero; return false; }