/////////////TESTEDGE0//////////////////////////////////// // testEdge0: // /// <summary> /// Test if the edges intersect with the ZERO convex. // The edges are given by the vertex vectors e[0-2] // All constraints are great circles, so test if their intersect // with the edges is inside or outside the convex. // If any edge intersection is inside the convex, return true. // If all edge intersections are outside, check whether one of // the corners is inside the triangle. If yes, all of them must be // inside -> return true. /// </summary> /// <param name="v0">vertex vector e[0]</param> /// <param name="v1">vertex vector e[1]</param> /// <param name="v2">vertex vector e[2]</param> /// <returns></returns> private bool testEdge0(Cartesian v0, Cartesian v1, Cartesian v2){ // We have constructed the corners_ array in a certain direction. // now we can run around the convex, check each side against the 3 // triangle edges. If any of the sides has its intersection INSIDE // the side, return true. At the end test if a corner lies inside // (because if we get there, none of the edges intersect, but it // can be that the convex is fully inside the triangle. so to test // one single edge is enough) edgeStruct[] edge = new edgeStruct[3]; if (_corners.Count < 1) { throw new Exception("testEdge0: There are no corners"); } // fill the edge structure for each side of this triangle Cartesian c01 = new Cartesian(v0); Cartesian c12 = new Cartesian(v1); Cartesian c20 = new Cartesian(v2); c01.crossMe(v1); c12.crossMe(v2); c20.crossMe(v0); edge[0].e = c01; edge[0].e1 = v0; edge[0].e2 = v1; edge[0].l = Math.Acos(v0.dot(v1)); edge[1].e = c12; edge[1].e1 = v1; edge[1].e2 = v2; edge[1].l = Math.Acos(v1.dot(v2)); edge[2].e = c20; edge[2].e1 = v2; edge[2].e2 = v0; edge[2].l = Math.Acos(v2.dot(v0)); // edge[0].e = v0 ^ v1; edge[0].e1 = &v0; edge[0].e2 = &v1; // edge[1].e = v1 ^ v2; edge[1].e1 = &v1; edge[1].e2 = &v2; // edge[2].e = v2 ^ v0; edge[2].e1 = &v2; edge[2].e2 = &v0; // edge[0].l = Acos(v0 * v1); // edge[1].l = Acos(v1 * v2); // edge[2].l = Acos(v2 * v0); for(int i = 0; i < _corners.Count; i++) { int j = 0; if(i < _corners.Count - 1){ j = i+1; } Cartesian a1 = new Cartesian(); Cartesian tmp; double arg1, arg2; double l1,l2; // lengths of the arcs from intersection to edge corners double cedgelen = Math.Acos( ((Cartesian) _corners[i]).dot ((Cartesian) _corners[j])); // length of edge of convex // calculate the intersection - all 3 edges for (int iedge = 0; iedge < 3; iedge++) { a1.assign(edge[iedge].e); tmp = ((Cartesian) _corners[i]).cross ((Cartesian) _corners[j]); a1.crossMe(tmp); if (a1.normalizeMeSafely()){ // WARNING // Keep your eye on this, used to crash here... // // if the intersection a1 is inside the edge of the convex, // its distance to the corners is smaller than the edgelength. // this test has to be done for both the edge of the convex and // the edge of the triangle. for(int k = 0; k < 2; k++) { l1 = Math.Acos(((Cartesian) _corners[i]).dot(a1)); l2 = Math.Acos(((Cartesian) _corners[j]).dot(a1)); if( l1 - cedgelen <= Cartesian.Epsilon && l2 - cedgelen <= Cartesian.Epsilon){ arg1 = (edge[iedge].e1).dot(a1); arg2 = (edge[iedge].e2).dot(a1); if (arg1 > 1.0) arg1 = 1.0; if (arg2 > 1.0) arg2 = 1.0; l1 = Math.Acos(arg1); l2 = Math.Acos(arg2); if( l1 - edge[iedge].l <= Cartesian.Epsilon && l2 - edge[iedge].l <= Cartesian.Epsilon) return true; } a1.scaleMe(-1.0); // do the same for the other intersection } } } } return testVectorInside(v0,v1,v2,(Cartesian) _corners[0]); }