public bool InsideOutsideCheck(Geometry.Triangle triangle, Vector3 point) { List <Vector3> trianglePoints = new List <Vector3>(); trianglePoints.Add(triangle.pointA); trianglePoints.Add(triangle.pointB); trianglePoints.Add(triangle.pointC); trianglePoints.Add(point); Sort(ref trianglePoints); List <Vector3> convexHull = GenerateConvexHull(trianglePoints); if (convexHull.Count == 3) { if (convexHull.Contains(point)) { return(false); } else { return(true); } } else { return(false); } }
void SubDivideTriangles() { bool triangleFound = false; for (int i = 0; i < innerPoints.Count; i++) { for (int j = 0; j < mTriangles.Count; j++) { triangleFound = InsideOutsideCheck(mTriangles[j], innerPoints[i]); if (triangleFound) { //Need to subdivide this triangle by creating a new triangle by drawing a line from the current inner point to all 3 vertices of the current triangle //That means: //Creating 3 new lines from the current point to points A, B and C of the current triangle //Keep track of these lines separately. PointToA, PointToB and PointToC //Construct 3 new Triangles from these new lines and the lines of the current triangle (subdivisions): //Delete the current Triangle from the list and add the 3 new triangles to the list. int x = 5; int y = x + 5; Geometry.Triangle temp = mTriangles[j]; mTriangles.Add(new Geometry.Triangle(innerPoints[i], temp.pointA, temp.pointB)); mTriangles.Add(new Geometry.Triangle(innerPoints[i], temp.pointB, temp.pointC)); mTriangles.Add(new Geometry.Triangle(innerPoints[i], temp.pointC, temp.pointA)); mTriangles.RemoveAt(j); break; } if (triangleFound) { break; } } } }
public static List <Vector3> FindPointsFormingAngle(Geometry.Triangle A, Vector3 pivotPoint) { List <Vector3> pointsInOrder = new List <Vector3>(); // ensure the list is in start-pivot-end order (put the pivot point in the middle) if (A.pointA == pivotPoint) { pointsInOrder.Add(A.pointB); pointsInOrder.Add(A.pointA); pointsInOrder.Add(A.pointC); } else if (A.pointB == pivotPoint) { pointsInOrder.Add(A.pointA); pointsInOrder.Add(A.pointB); pointsInOrder.Add(A.pointC); } else if (A.pointC == pivotPoint) { pointsInOrder.Add(A.pointA); pointsInOrder.Add(A.pointC); pointsInOrder.Add(A.pointB); } return(pointsInOrder); }
void Verify(Geometry.Triangle t, Vector2 c, float r2) { var az = (t.A - c).LengthSquared(); var bz = (t.B - c).LengthSquared(); var cz = (t.C - c).LengthSquared(); Assert.True(Math.Abs(az - bz) < 0.001); // radials from centre to each point should have equal length Assert.True(Math.Abs(az - cz) < 0.001); Assert.True(Math.Abs(az - r2) < 0.001); // radial lengths should match returned radius }
public void ScaleneTest() { var a = new Vector2(12, 0); var b = new Vector2(-6, -4); var c = new Vector2(7.2f, 8.1f); var triangle = new Geometry.Triangle(a, b, c); var(z, r2) = triangle.Circumcircle(); Verify(triangle, z, r2); }
public void ColocatedTest() { var a = new Vector2(0, 0); var b = new Vector2(0, 0); var c = new Vector2(0, 0); var triangle = new Geometry.Triangle(a, b, c); var(z, r2) = triangle.Circumcircle(); Assert.Equal(float.NaN, z.X); Assert.Equal(float.NaN, z.Y); Assert.Equal(float.NaN, r2); }
public void ColinearTest() { var a = new Vector2(-1, 0); var b = new Vector2(0, 0); var c = new Vector2(1, 0); var triangle = new Geometry.Triangle(a, b, c); var(z, r2) = triangle.Circumcircle(); Assert.Equal(float.NaN, z.X); Assert.Equal(float.PositiveInfinity, z.Y); Assert.Equal(float.NaN, r2); }
public void IsoscelesTest() { var a = new Vector2(-0.5f, 0); var b = new Vector2(0.5f, 0); var c = new Vector2(0, 2); Assert.True(Math.Abs((a - c).Length() - (b - c).Length()) < float.Epsilon); var triangle = new Geometry.Triangle(a, b, c); var(z, r2) = triangle.Circumcircle(); Verify(triangle, z, r2); }
public void EquilateralTest() { var a = new Vector2(-1, 0); var b = new Vector2(1, 0); var c = new Vector2(0, (float)Math.Sqrt(3)); Assert.True(Math.Abs((a - b).Length() - 2) < float.Epsilon); Assert.True(Math.Abs((b - c).Length() - 2) < float.Epsilon); Assert.True(Math.Abs((c - a).Length() - 2) < float.Epsilon); var triangle = new Geometry.Triangle(a, b, c); var(z, r2) = triangle.Circumcircle(); Verify(triangle, z, r2); }
public static Vector3 FindUncommonPoint(Geometry.Triangle A, Geometry.Triangle B) { List <Vector3> APoints = new List <Vector3>(); APoints.Add(A.pointA); APoints.Add(A.pointB); APoints.Add(A.pointC); for (int i = 0; i < 3; i++) { if (APoints[i] != B.pointA && APoints[i] != B.pointB && APoints[i] != B.pointC) { return(APoints[i]); } } throw new System.Exception(); }
public static Geometry.Circle CalculateCircumcircle(Geometry.Triangle triangle) { Vector3[] midpoints = new Vector3[3]; Vector3[] bisectors = new Vector3[3]; Geometry.Line[] edges = new Geometry.Line[3]; for (int i = 0; i < 3; i++) { midpoints[i] = CalculateMidpoint(triangle.lines[i]); Vector3 temp = midpoints[i] - triangle.lines[i].start; bisectors[i].x = -temp.z; bisectors[i].y = 0.0f; bisectors[i].z = temp.x; } edges[0] = new Geometry.Line(midpoints[0], bisectors[0] + midpoints[0]); edges[1] = new Geometry.Line(midpoints[1], bisectors[1] + midpoints[1]); edges[2] = new Geometry.Line(midpoints[2], bisectors[2] + midpoints[2]); Vector3[] intersectionPoints = new Vector3[3]; intersectionPoints[0] = FindIntersection(edges[0], edges[1]); intersectionPoints[1] = FindIntersection(edges[1], edges[2]); intersectionPoints[2] = FindIntersection(edges[2], edges[0]); bool isCenter = (intersectionPoints[0] == intersectionPoints[1] && intersectionPoints[1] == intersectionPoints[2]); Vector3 vertexPosition = edges[0].start; Vector3 circlePosition = intersectionPoints[0]; float distanceA = Vector3.Distance(triangle.pointA, circlePosition); float distanceB = Vector3.Distance(triangle.pointB, circlePosition); float distanceC = Vector3.Distance(triangle.pointC, circlePosition); bool equidistance = (distanceA == distanceB && distanceB == distanceC); float maxDistance = Mathf.Max(distanceA, distanceB, distanceC); return(new Geometry.Circle(circlePosition, maxDistance)); }
public int FindTriangleIndex(Geometry.Triangle A) { //what i really wanna check. does this triangle have 3 points in common. for (int i = 0; i < mTriangles.Count; i++) { bool aTrue = false; bool bTrue = false; bool cTrue = false; if (Mathf.Approximately(A.pointA.x, mTriangles[i].pointA.x)) { if (Mathf.Approximately(A.pointA.y, mTriangles[i].pointA.y)) { aTrue = true; } } if (Mathf.Approximately(A.pointB.x, mTriangles[i].pointB.x)) { if (Mathf.Approximately(A.pointB.y, mTriangles[i].pointB.y)) { bTrue = true; } } if (Mathf.Approximately(A.pointC.x, mTriangles[i].pointC.x)) { if (Mathf.Approximately(A.pointC.y, mTriangles[i].pointC.y)) { cTrue = true; } } if (aTrue && bTrue && cTrue) { return(i); } } return(-1); }
public bool Adjacent(Geometry.Triangle A, Geometry.Triangle B) { int count = 0; bool AA = A.pointA == B.pointA || A.pointA == B.pointB || A.pointA == B.pointC; bool AB = A.pointB == B.pointA || A.pointB == B.pointB || A.pointB == B.pointC; bool AC = A.pointC == B.pointA || A.pointC == B.pointB || A.pointC == B.pointC; if (AA) { count++; } if (AB) { count++; } if (AC) { count++; } return(count == 2); }
public int DelaunayPass(List <Geometry.Triangle> triangles, int pointCount) { int numPoints = 0; int ret = 0; List <Vector3> pointsInCircle = new List <Vector3>(); for (int triIndex = 0; triIndex < triangles.Count; triIndex++) // use the original list's size. go until the end of the list. { pointsInCircle.Clear(); for (int index = 0; index < allPoints.Count; index++) { if (Geometry.PointInsideCircle(mTriangles[triIndex].circumCircle, allPoints[index])) { pointsInCircle.Add(allPoints[index]); mTriangles[triIndex].numPointsInCircle++; } } numPoints = pointsInCircle.Count; if (numPoints >= 4) { List <Geometry.Triangle> trianglesWithPoint = new List <Geometry.Triangle>(); for (int pointIndex = 0; pointIndex < pointsInCircle.Count; pointIndex++) { for (int triangleIndex = 0; triangleIndex < triangles.Count; triangleIndex++) { if (mTriangles[triangleIndex].pointA == pointsInCircle[pointIndex] || mTriangles[triangleIndex].pointB == pointsInCircle[pointIndex] || mTriangles[triangleIndex].pointC == pointsInCircle[pointIndex]) { trianglesWithPoint.Add(mTriangles[triangleIndex]); } } for (int k = 0; k < trianglesWithPoint.Count; k++) { if (Adjacent(mTriangles[triIndex], trianglesWithPoint[k])) { //find the uncommon points Vector3[] edgeFlipPoints = new Vector3[4]; Vector3 uncommonPoint = Geometry.FindUncommonPoint(mTriangles[triIndex], trianglesWithPoint[k]); edgeFlipPoints[0] = uncommonPoint; List <Vector3> pointsFormingAngle = Geometry.FindPointsFormingAngle(mTriangles[triIndex], uncommonPoint); edgeFlipPoints[1] = pointsFormingAngle[0]; edgeFlipPoints[2] = pointsFormingAngle[2]; float theta1 = Mathf.Ceil(180 - Geometry.CalculateAngleInDegs(pointsFormingAngle[0], pointsFormingAngle[1], pointsFormingAngle[2])); uncommonPoint = Geometry.FindUncommonPoint(trianglesWithPoint[k], mTriangles[triIndex]); edgeFlipPoints[3] = uncommonPoint; pointsFormingAngle.Clear(); pointsFormingAngle = Geometry.FindPointsFormingAngle(trianglesWithPoint[k], uncommonPoint); float theta2 = Mathf.Ceil(180 - Geometry.CalculateAngleInDegs(pointsFormingAngle[0], pointsFormingAngle[1], pointsFormingAngle[2])); //check if the sum of the angles made of their uncommon edges is greater than 180 degrees //if angle > 180 flip their edges: if (theta1 + theta2 >= 180) { //Mark these two triangles for flipping Vector2 indexPair = new Vector2(FindTriangleIndex(mTriangles[triIndex]), FindTriangleIndex(trianglesWithPoint[k])); //Triangles P1P2P3 and P2P4P3 when flipped form new triangles P1P2P4 and P1P4P3 //int removeIndex = FindTriangleIndex(mTriangles[triIndex]); mTriangles.Remove(mTriangles[triIndex]); //removeIndex = FindTriangleIndex(trianglesWithPoint[k]); mTriangles.Remove(trianglesWithPoint[k]); Geometry.Triangle temp1 = new Geometry.Triangle(edgeFlipPoints[0], edgeFlipPoints[1], edgeFlipPoints[3]); Geometry.Triangle temp2 = new Geometry.Triangle(edgeFlipPoints[0], edgeFlipPoints[3], edgeFlipPoints[2]); for (int i = 0; i < allPoints.Count; i++) { if (Geometry.PointInsideCircle(temp1.circumCircle, allPoints[i])) { temp1.numPointsInCircle++; } if (Geometry.PointInsideCircle(temp2.circumCircle, allPoints[i])) { temp2.numPointsInCircle++; } } mTriangles.Add(temp1); mTriangles.Add(temp2); continue; } } } trianglesWithPoint.Clear(); } } ret = Mathf.Max(ret, numPoints); } return(ret); }