public PointInPoly PointInPolyhedron(xyz p) { WhichSideOfPlane sid = tri.Classify(p); Debug.Assert( (sid == WhichSideOfPlane.Inside) || (sid == WhichSideOfPlane.Outside) || (sid == WhichSideOfPlane.Coplanar) ); if (sid == WhichSideOfPlane.Inside) { if (inside != null) { return(inside.PointInPolyhedron(p)); } else { return(PointInPoly.Inside); } } else if (sid == WhichSideOfPlane.Outside) { if (outside != null) { return(outside.PointInPolyhedron(p)); } else { return(PointInPoly.Outside); } } else { // coplanar if (tri.PointInside(p)) { return(PointInPoly.Coincident); } if (coincident != null) { foreach (Triangle3d tc in coincident) { if (tc.PointInside(p)) { return(PointInPoly.Coincident); } } } if (inside != null) { return(inside.PointInPolyhedron(p)); } else // if (outside != null) { Debug.Assert(outside != null); return(outside.PointInPolyhedron(p)); }
// TODO note that this method isn't used except in the unit tests internal void Split(Triangle3d t, List <Triangle3d> tris_in, List <Triangle3d> tris_out) { Debug.Assert(tris_in != null); Debug.Assert(tris_out != null); Debug.Assert(tris_in.Count == 0); Debug.Assert(tris_out.Count == 0); WhichSideOfPlane sa; WhichSideOfPlane sb; WhichSideOfPlane sc; Classify(t.a, out sa, t.b, out sb, t.c, out sc); Debug.Assert(this.Classify(t) == WhichSideOfPlane.Split); xyz ab; xyz bc; xyz ca; FindSegmentIntersectionWithPlane(t.a, t.b, out ab); FindSegmentIntersectionWithPlane(t.b, t.c, out bc); FindSegmentIntersectionWithPlane(t.c, t.a, out ca); Triangle3d t1, t2, t3; if ( (ab == null) && (bc != null) && (ca == null) ) { // the plane passes through a. the result is one tri on each side. t1 = new Triangle3d(t.a, t.b, bc); t2 = new Triangle3d(t.a, bc, t.c); if (sb == WhichSideOfPlane.Inside) { tris_in.Add(t1); tris_out.Add(t2); } else { tris_in.Add(t2); tris_out.Add(t1); } } else if ( (ab != null) && (bc == null) && (ca == null) ) { // the plane passes through t.c t1 = new Triangle3d(t.a, ab, t.c); t2 = new Triangle3d(t.b, t.c, ab); if (sa == WhichSideOfPlane.Inside) { tris_in.Add(t1); tris_out.Add(t2); } else { tris_in.Add(t2); tris_out.Add(t1); } } else if ( (ab == null) && (bc == null) && (ca != null) ) { // the plane passes through t.b t1 = new Triangle3d(t.a, t.b, ca); t2 = new Triangle3d(t.c, ca, t.b); if (sa == WhichSideOfPlane.Inside) { tris_in.Add(t1); tris_out.Add(t2); } else { tris_in.Add(t2); tris_out.Add(t1); } } else if ( (ab != null) && (bc == null) && (ca != null) ) { // the plane cuts through ab and ca. t.b and t.c are one side, t.a is on the other t1 = new Triangle3d(t.a, ab, ca); t2 = new Triangle3d(t.b, ca, ab); t3 = new Triangle3d(t.c, ca, t.b); if (sa == WhichSideOfPlane.Inside) { tris_in.Add(t1); tris_out.Add(t2); tris_out.Add(t3); } else { tris_out.Add(t1); tris_in.Add(t2); tris_in.Add(t3); } } else if ( (ab != null) && (bc != null) && (ca == null) ) { // the plane cuts through ab and bc. t.a and t.c are one side, t.b is on the other t1 = new Triangle3d(t.b, bc, ab); t2 = new Triangle3d(t.a, ab, bc); t3 = new Triangle3d(t.c, t.a, bc); if (sb == WhichSideOfPlane.Inside) { tris_in.Add(t1); tris_out.Add(t2); tris_out.Add(t3); } else { tris_out.Add(t1); tris_in.Add(t2); tris_in.Add(t3); } } else if ( (ab == null) && (bc != null) && (ca != null) ) { // the plane cuts through bc and ca. t.a and t.b are one side, t.c is on the other t1 = new Triangle3d(t.c, ca, bc); t2 = new Triangle3d(t.a, t.b, bc); t3 = new Triangle3d(t.a, bc, ca); if (sc == WhichSideOfPlane.Inside) { tris_in.Add(t1); tris_out.Add(t2); tris_out.Add(t3); } else { tris_out.Add(t1); tris_in.Add(t2); tris_in.Add(t3); } } Debug.Assert(tris_in.Count > 0); Debug.Assert(tris_out.Count > 0); #if BSP_DEBUG xyz n = t.normal().normalize(); foreach (Triangle3d tq in tris_in) { Console.Out.WriteLine("Split: inside: {0} -- {1} -- {2}", tq.a, tq.b, tq.c); xyz nq = tq.normal().normalize(); if (!ut.eq(n, nq)) { throw new ShouldNeverHappenException("normals wrong"); } WhichSideOfPlane wsop = this.Classify(tq); if (wsop != WhichSideOfPlane.Inside) { throw new ShouldNeverHappenException("should be inside"); } } foreach (Triangle3d tq in tris_out) { Console.Out.WriteLine("Split: outside: {0} -- {1} -- {2}", tq.a, tq.b, tq.c); xyz nq = tq.normal().normalize(); if (!ut.eq(n, nq)) { throw new ShouldNeverHappenException("normals wrong"); } WhichSideOfPlane wsop = this.Classify(tq); if (wsop != WhichSideOfPlane.Outside) { throw new ShouldNeverHappenException("should be Outside"); } } Console.Out.WriteLine(); #endif }
internal void Classify(xyz a, out WhichSideOfPlane sa, xyz b, out WhichSideOfPlane sb, xyz c, out WhichSideOfPlane sc) { sa = Classify(a); sb = Classify(b); sc = Classify(c); }