예제 #1
0
		/////////////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]);
		}