public static Vector4 GetInternalAnglesQuadUnitSphere(Vector3 a, Vector3 b, Vector3 c, Vector3 d) { var angles = new UnitSpherePolygon(new List <Vector3> { a, b, c, d }).GetInternalAngles(); return(new Vector4(angles[0], angles[1], angles[2], angles[3])); }
private float ProcessVertex(int vertexIndex, FaceIndexTriplet[] connectedTriangles, Vector3[] vertices) { if (connectedTriangles.Length < 1) { return(0.0f); } var normalInfo = CreatePivotNormalForVertex(vertexIndex, connectedTriangles, vertices, true); var pivotNormal = normalInfo.Pivot; var triangleNormals = normalInfo.TriangleNormals; _pivotNormals.Add(vertexIndex, pivotNormal); //We have our pivot normal now, so it's time to project the other vertices around this normal //as they only occupy the half of the unit sphere where dot(n, p) > 0 //This allows us to project them down onto the plane and order them var projectedNormals = new List <Vector3>(triangleNormals.Count); foreach (var triangleNormal in triangleNormals) { projectedNormals.Add(Vector3.ProjectOnPlane(triangleNormal, pivotNormal)); } //Now we have a plane with the normal vectors projected onto it, now we can use their angular difference //from an arbitrary vector within the set, to order them var angularOrigin = projectedNormals[0]; var angleNormalPairs = new SortedDictionary <float, Vector3>(); for (var i = 0; i < projectedNormals.Count; i++) { var projectedNormal = projectedNormals[i]; var angle = Vector3.SignedAngle(angularOrigin, projectedNormal, pivotNormal); if (!angleNormalPairs.ContainsKey(angle)) { angleNormalPairs.Add(angle, triangleNormals[i]); } } var sortedNormals = new List <Vector3>(projectedNormals.Count); foreach (var angleNormalPair in angleNormalPairs) { sortedNormals.Add(angleNormalPair.Value); } var polygon = new UnitSpherePolygon(sortedNormals); //_vertexNormalPolygons.Add(vertexIndex, polygon); var area = polygon.GetArea(); return(area); }
private float ProcessFace(Vector3 n0, Vector3 n1, Vector3 n2) { var sortedVertices = CircularlySortNormals(new List <Vector3> { n0, n1, n2 }); UnitSpherePolygon poly = new UnitSpherePolygon(sortedVertices); return(poly.GetArea()); }
private float ProcessEdge(EdgeIndices edge, FaceIndexTriplet[] connectedTriangles, Vector3[] vertices) { var v1 = vertices[edge.I1]; var v2 = vertices[edge.I2]; var dv = (v2 - v1).normalized; var n1 = _pivotNormals[edge.I1]; var n2 = _pivotNormals[edge.I2]; var ne = (n1 + n2).normalized; var side1 = Vector3.Cross(ne, dv).normalized; var side2 = -side1; //For v1 on side 1: //get the triangle edges on side 1 (dot(n1, v1-t1) should be more than 0) //where v1 is the vertex and t1 the side of the triangle pointing away from the vertex //then check if said triangles are actually connected to v1 (might be faster to do it the other way around, idk) //Side 1 var nS1V1 = CalculateSidedPivot(edge.I1, connectedTriangles, side1, ne, dv, vertices); var nS1V2 = CalculateSidedPivot(edge.I2, connectedTriangles, side1, ne, dv, vertices); //Side 2 var nS2V1 = CalculateSidedPivot(edge.I1, connectedTriangles, side2, ne, dv, vertices); var nS2V2 = CalculateSidedPivot(edge.I2, connectedTriangles, side2, ne, dv, vertices); var polygon = new UnitSpherePolygon(CircularlySortNormals(new List <Vector3> { nS1V1, nS1V2, nS2V1, nS2V2 })); return(polygon.GetArea()); }