From f0d276eb2323a63637d0feab66b46787e11caa84 Mon Sep 17 00:00:00 2001 From: Ryan Schmidt Date: Tue, 13 Dec 2016 00:02:41 -0500 Subject: [PATCH] various utility stuff --- math/IndexUtil.cs | 16 +++++++++++++ math/MathUtil.cs | 29 ++++++++++++++++++++++++ math/Vector3d.cs | 4 ++++ mesh/DMesh3.cs | 57 ++++++++++++++++++++++++++++++++++++++--------- 4 files changed, 95 insertions(+), 11 deletions(-) diff --git a/math/IndexUtil.cs b/math/IndexUtil.cs index f50dffc4..6c72ca8b 100644 --- a/math/IndexUtil.cs +++ b/math/IndexUtil.cs @@ -20,6 +20,13 @@ public static int find_tri_index(int a, int[] tri_verts) if (tri_verts[2] == a) return 2; return DMesh3.InvalidID; } + public static int find_tri_index(int a, Vector3i tri_verts) + { + if (tri_verts[0] == a) return 0; + if (tri_verts[1] == a) return 1; + if (tri_verts[2] == a) return 2; + return DMesh3.InvalidID; + } // return index of a in tri_verts, or InvalidID if not found public static int find_edge_index_in_tri(int a, int b, int[] tri_verts ) @@ -56,6 +63,15 @@ public static int find_tri_other_vtx(int a, int b, Vector3i tri_verts) } return DMesh3.InvalidID; } + public static int find_tri_other_vtx(int a, int b, DVector tri_array, int ti) + { + int i = 3*ti; + for (int j = 0; j < 3; ++j) { + if (same_pair_unordered(a, b, tri_array[i+j], tri_array[i + ((j + 1) % 3)])) + return tri_array[i + ((j + 2) % 3)]; + } + return DMesh3.InvalidID; + } // find sequence [a,b] in tri_verts (mod3) then return the third **index**, or InvalidID if not found public static int find_tri_other_index(int a, int b, int[] tri_verts) diff --git a/math/MathUtil.cs b/math/MathUtil.cs index b09139cd..409fa8be 100644 --- a/math/MathUtil.cs +++ b/math/MathUtil.cs @@ -182,5 +182,34 @@ public static float LinearRampT(float R, float deadzoneR, float x) } + + public static double Area(Vector3d v1, Vector3d v2, Vector3d v3) { + return 0.5 * (v2 - v1).Cross(v3 - v1).Length; + } + + //! fast cotangent between two normalized vectors + //! returns zero if result would be unstable (eg infinity) + // formula from http://www.geometry.caltech.edu/pubs/DMSB_III.pdf + public static double VectorCot( Vector3d v1, Vector3d v2 ) + { + double fDot = v1.Dot(v2); + double lensqr1 = v1.LengthSquared; + double lensqr2 = v2.LengthSquared; + double d = MathUtil.Clamp(lensqr1 * lensqr2 - fDot*fDot, 0.0f, Double.MaxValue); + if ( d < MathUtil.ZeroTolerance ) + return 0; + else + return fDot / Math.Sqrt( d ); + } + + + public static bool IsObtuse(Vector3d v1, Vector3d v2, Vector3d v3) { + double a2 = v1.DistanceSquared(v2); + double b2 = v1.DistanceSquared(v3); + double c2 = v2.DistanceSquared(v3); + return (a2+b2 < c2) || (b2+c2 < a2) || (c2+a2 < b2); + } + + } } diff --git a/math/Vector3d.cs b/math/Vector3d.cs index 93dab08d..450f5dbc 100644 --- a/math/Vector3d.cs +++ b/math/Vector3d.cs @@ -119,6 +119,10 @@ public static double AngleR(Vector3d v1, Vector3d v2) return v1.AngleR(v2); } + public double DistanceSquared(Vector3d v2) { + double dx = v2.x-x, dy = v2.y-y, dz = v2.z-z; + return dx*dx + dy*dy + dz*dz; + } public void Set(Vector3d o) { diff --git a/mesh/DMesh3.cs b/mesh/DMesh3.cs index c31b6056..093aec20 100644 --- a/mesh/DMesh3.cs +++ b/mesh/DMesh3.cs @@ -219,15 +219,6 @@ public ReadOnlyCollection GetVtxEdges(int vID) { vertex_edges[vID].AsReadOnly() : null; } - public IEnumerable VtxVerticesItr(int vID) { - if ( vertices_refcount.isValid(vID) ) { - List edges = vertex_edges[vID]; - int N = edges.Count; - for ( int i = 0; i < N; ++i ) - yield return edge_other_v(edges[i], vID); - } - } - public NewVertexInfo GetVertexAll(int i) { NewVertexInfo vi = new NewVertexInfo(); vi.v = GetVertex(i); @@ -411,14 +402,16 @@ public System.Collections.IEnumerable EdgeIndices() { int FindEdge(int vA, int vB) { return find_edge(vA, vB); } + + // [RMS] this does more work than necessary, see Vector2i GetEdgeOpposingV(int eID) { int i = 4*eID; int a = edges[i], b = edges[i + 1]; int t0 = edges[i + 2], t1 = edges[i + 3]; - int c = IndexUtil.orient_tri_edge_and_find_other_vtx(ref a, ref b, GetTriangle(t0).array); + int c = IndexUtil.find_tri_other_vtx(a, b, triangles, t0); if (t1 != InvalidID) { - int d = IndexUtil.find_tri_other_vtx(a, b, GetTriangle(t1).array); + int d = IndexUtil.find_tri_other_vtx(a, b, triangles, t1); return new Vector2i(c, d); } else return new Vector2i(c, InvalidID); @@ -426,6 +419,16 @@ Vector2i GetEdgeOpposingV(int eID) + public IEnumerable VtxVerticesItr(int vID) { + if ( vertices_refcount.isValid(vID) ) { + List edges = vertex_edges[vID]; + int N = edges.Count; + for ( int i = 0; i < N; ++i ) + yield return edge_other_v(edges[i], vID); + } + } + + Vector3i GetTriTriangles(int tID) { if (!IsTriangle(tID)) return InvalidTriangle; @@ -468,10 +471,42 @@ MeshResult GetVtxTriangles(int vID, List vTriangles, bool bUseOrientation) return MeshResult.Ok; } + + public IEnumerable VtxTrianglesItr(int vID) { + if ( IsVertex(vID) ) { + List vedges = vertex_edges[vID]; + foreach (int eid in vedges) { + int vOther = edge_other_v(eid, vID); + int i = 4*eid; + int et0 = edges[i + 2]; + if (tri_has_sequential_v(et0, vID, vOther)) + yield return et0; + int et1 = edges[i + 3]; + if (et1 != InvalidID && tri_has_sequential_v(et1, vID, vOther)) + yield return et1; + } + } + } + + public int GetVtxEdgeValence(int vID) { return vertex_edges[vID].Count; } + // from edge and vert, returns other vert, two opposing verts, and two triangles + public void GetVtxNbrhood(int eID, int vID, ref int vOther, ref int oppV1, ref int oppV2, ref int t1, ref int t2) + { + int i = 4*eID; + vOther = (edges[i] == vID) ? edges[i+1] : edges[i]; + t1 = edges[i + 2]; + oppV1 = IndexUtil.find_tri_other_vtx(vID, vOther, triangles, t1); + t2 = edges[i + 3]; + if ( t2 != InvalidID ) + oppV2 = IndexUtil.find_tri_other_vtx(vID, vOther, triangles, t2); + else + t2 = InvalidID; + } + public bool tri_has_v(int tID, int vID) { int i = 3*tID;