Esempio n. 1
0
		/// <summary>
		/// Copy constructor.
		/// </summary>
		/// <param name="v">A Cartesian from which to copy</param>
		public SpatialVector(Cartesian v) {
			_x = v.x;
			_y = v.y;
			_z = v.z;
			_okXYZ = false;
			// updateRaDec();
		}
Esempio n. 2
0
		private Convex.Markup testTriangle(
			Cartesian v0, Cartesian v1, Cartesian v2,
			int vsum){

			Halfspace hs;
			if(vsum == 1 || vsum == 2){
				return Markup.Partial;
			}

			// If vsum = 3 then we have all vertices inside the convex.
			// Now use the following decision tree:
			//
			// * If the sign of the convex is POS or ZERO : mark as FULL intersection.
			//
			// * Else, test for holes inside the triangle. A 'hole' is a NEG constraint
			//   that has its center inside the triangle. If there is such a hole,
			//   return PARTIAL intersection.
			//
			// * Else (no holes, sign NEG or MIXED) test for intersection of NEG
			//   constraints with the edges of the triangle. If there are such,
			//   return PARTIAL intersection.
			//
			// * Else return FULL intersection.

			if(vsum == 3) {
				if(_sign == Halfspace.Sign.Positive || _sign == Halfspace.Sign.Zero){
					return Markup.Full;
				}
				if ( testHole(v0,v1,v2) ) {
					return Markup.Partial;
				}
				if ( testEdge(v0,v1,v2) ) {
					return Markup.Partial;
				}
				return Markup.Full;
			}

			// If we have reached that far, we have vsum=0. There is no definite
			// decision making possible here with our methods, the markup may result
			// in DONTKNOW. The decision tree is the following:
			//
			// * Test with bounding circle of the triangle.
			//
			//   # If the sign of the convex ZERO test with the precalculated
			//     bounding circle of the convex. If it does not intersect with the
			//     triangle's bounding circle, REJECT.
			//
			//   # If the sign of the convex is nonZERO: if the bounding circle
			//     lies outside of one of the constraints, REJECT.
			//
			// * Else: there was an intersection with the bounding circle.
			//
			//   # For ZERO convexes, test whether the convex intersects the edges.
			//     If none of the edges of the convex intersects with the edges of
			//     the triangle, we have a REJECT. Else, PARTIAL.
			//
			//   # If sign of convex is POS, or MIXED and the smallest constraint does
			//     not intersect the edges and has its center inside the triangle,
			//     return SWALLOW. If no intersection of edges and center outside
			//     triangle, return REJECT.
			//
			//   # So the smallest constraint DOES intersect with the edges. If
			//     there is another POS constraint which does not intersect with
			//     the edges, and has its center outside the triangle, return
			//     REJECT. If its center is inside the triangle return SWALLOW.
			//     Else, return PARTIAL for POS and DONTKNOW for MIXED signs.
			//
			// * If we are here, return DONTKNOW. There is an intersection with
			//   the bounding circle, none of the vertices is inside the convex and
			//   we have very strange possibilities left for POS and MIXED signs. For
			//   NEG, i.e. all constraints negative, we also have some complicated
			//   things left for which we cannot test further.

			if ( !testBoundingCircle(v0,v1,v2) ) {
				return Markup.Reject;
			}

			if ( _sign == Halfspace.Sign.Positive ||
				_sign == Halfspace.Sign.Mixed || 
				(_sign == Halfspace.Sign.Zero && _halfspaces.Count <= 2)) {
				// Does the smallest constraint intersect with the edges?
				if ( testEdgeConstraint(v0,v1,v2,0) ) {
					// Is there another positive constraint that does NOT intersect with
					// the edges? cIndex is the position in _halspaces
					int cIndex;
					if ((cIndex = testOtherPosNone(v0,v1,v2))>= 0) {
						// Does that constraint lie inside or outside of the triangle?
						if ( testConstraintInside(v0,v1,v2, cIndex) ){
							return Markup.Partial;
						} else if( (hs = (Halfspace)_halfspaces[cIndex]).contains(v0) ){
							// Does the triangle lie completely within that constr?
							return Markup.Partial;
						} else {
							return Markup.Reject; // FIXED:was: Markup.Partial;
						}
					} else {
						if(_sign == Halfspace.Sign.Positive || 
							_sign == Halfspace.Sign.Zero){
							return Markup.Partial;
						} else {
							return Markup.Dontknow;
						}
					}
				} else {
					if (_sign == Halfspace.Sign.Positive || 
						_sign == Halfspace.Sign.Zero) {
						// Does the smallest lie inside or outside the triangle?
						if( testConstraintInside(v0,v1,v2, 0)){
							return Markup.Partial;
						} else {
							return Markup.Reject;
						}
					} else {
						return Markup.Dontknow;
					}
				}
			} else if (_sign == Halfspace.Sign.Zero) {
				if (_halfspaces.Count > 0 && testEdge0(v0,v1,v2)){
					return Markup.Partial;
				} else {
					return Markup.Reject;
				}
			}
			return Markup.Partial;
		}
Esempio n. 3
0
		/// <summary>
		/// Test whether or not this vector is equal to
		/// another vector
		/// </summary>
		/// <param name="that">The other vector</param>
		/// <returns>true if other vector is close enough,
		/// false otherwise</returns>
		public bool eq(Cartesian that){
			if (Math.Abs(that._x - _x) > Epsilon)
				return false;
			if (Math.Abs(that._y - _y) > Epsilon)
				return false;
			if (Math.Abs(that._z - _z) > Epsilon)
				return false;
			return true;
		}
Esempio n. 4
0
		/// <summary>
		/// Perform cross product of this and another vector.
		/// The result is a new cartesian instance.
		/// </summary>
		/// <param name="that">The other vector</param>
		/// <returns>The cross product as a new Cartesian</returns>
		public Cartesian cross(Cartesian that){
			return new Cartesian(
				y*that.z - z*that.y,
				z*that.x - x*that.z,
				x*that.y - y*that.x);
		}
Esempio n. 5
0
		/// <summary>
		/// Subtract other vector from this, but create a new instance with 
		///	the result.
		/// </summary>
		/// <param name="that">The other Cartesian</param>
		/// <returns>the difference as a new Catesian</returns>
		public Cartesian sub(Cartesian that){
			return new Cartesian(
				_x - that._x,
				_y - that._y,
				_z - that._z);
		}
Esempio n. 6
0
		/// <summary>
		/// Make this vector the same as the other (given) one.
		/// </summary>
		/// <param name="that">The other Cartesian</param>
		public void assign(Cartesian that){
			_x = that._x;
			_y = that._y;
			_z = that._z;
		}
Esempio n. 7
0
		/// <summary>
		/// Compute cross product  of two given vectors.
		/// Result is written into a suppied Cartesian
		/// </summary>
		/// <param name="t">the result of operation</param>
		/// <param name="u">Array of 3 doubles with (x,y,z)</param>
		/// <param name="v">Array of 3 doubles with (x,y,z)</param>
		public static void cross(Cartesian t, double[] u, double[] v){
			t.x = u[1] * v[2] - u[2] * v[1];
			t.y = u[2] * v[0] - u[0] * v[2];
			t.z = u[0] * v[1] - u[1] * v[0];
			return;
		}
Esempio n. 8
0
		/// <summary>
		/// Compute dot product of this and a given vector
		/// </summary>
		/// <param name="that">The other Cartesian</param>
		/// <returns>The dot product</returns>
		public double dot(Cartesian that) {
			return x*that.x + y*that.y + z*that.z;
		}
Esempio n. 9
0
		} // end METHOD testBoundingCircle
		
		/// <summary>
		/// Test if edges intersect with a given constraint.
		/// </summary>
		/// <param name="v0"></param>
		/// <param name="v1"></param>
		/// <param name="v2"></param>
		/// <param name="cIndex"></param>
		/// <returns>true if edges intersect with the constraint</returns>
		private bool testEdgeConstraint(Cartesian v0, Cartesian v1, Cartesian v2, int cIndex){

			if ( eSolve(v0, v1, cIndex) ) return true;
			if ( eSolve(v1, v2, cIndex) ) return true;
			if ( eSolve(v2, v0, cIndex) ) return true;
			return false;
		}
Esempio n. 10
0
		} // METHOD


		/// <summary>
		/// Test for boundingCircles intersecting with halfspace
		/// </summary>
		/// <param name="v0"></param>
		/// <param name="v1"></param>
		/// <param name="v2"></param>
		/// <returns></returns>
		private bool testBoundingCircle(Cartesian v0, Cartesian v1, Cartesian v2){

			// Set the correct direction: The normal vector to the triangle plane
			//Cartesian c = ( v1 - v0 ) ^ ( v2 - v1 );
			//c.normalize();

			Cartesian c = new Cartesian(v1);
			c.subMe(v0);

			Cartesian t = new Cartesian(v2);
			t.subMe(v1);

			c.crossMe(t);
			c.normalizeMe();

			// Set the correct opening angle: Since the plane cutting out the triangle
			// also correctly cuts out the bounding cap of the triangle on the sphere,
			// we can take any corner to calculate the opening angle
			double d = Math.Acos (c.dot(v0));

			// for zero convexes, we have calculated a bounding circle for the convex.
			// only test with this single bounding circle.
			//
			// NOTE! Bounding circle gets changed by simplify0
			// If you did not run simplify, bounding circle may contain
			// unpredictable numbers.
			//
			if(_sign == Halfspace.Sign.Zero && _boundingCircle != null) {
				double tst;
				tst = (tst = c.dot(_boundingCircle.sv));
				if ((tst < -1.0 + Cartesian.Epsilon ? Cartesian.Pi : Math.Acos(tst)) >
					(d + _boundingCircle.hangle)) return false;
				return true;
			}

			// for all other convexes, test every constraint. If the bounding
			// circle lies completely outside of one of the constraints, reject.
			// else, accept.

			int i;
			double ftmp;
			Halfspace hs;
			for(i = 0; i < _halfspaces.Count; i++) {
				hs = (Halfspace) _halfspaces[i];
				if (c.dot(hs.sv) < -1.0 + Cartesian.Epsilon){
					ftmp = Cartesian.Pi;
				} else {
					ftmp = Math.Acos(c.dot(hs.sv));
				}
				if (ftmp > (d + hs.hangle)){
					return false;
				}
			}
			return true;
		} // end METHOD testBoundingCircle
Esempio n. 11
0
		/// <summary>
		/// Solve the quadratic eq. for intersection of an edge with a circle
		/// halfspace. Edge given by great circle running through v1, v2
		/// halfspace given by cIndex.
		/// </summary>
		/// <param name="v1"></param>
		/// <param name="v2"></param>
		/// <param name="cIndex"></param>
		/// <returns></returns>
		private bool eSolve(Cartesian v1, Cartesian v2, int cIndex){
			Halfspace hs;
			hs = (Halfspace) _halfspaces[cIndex];

			double gamma1 = v1.dot(hs.sv);
			double gamma2 = v2.dot(hs.sv);
			double mu     = v1.dot(v2);
			double u2     = (1.0 - mu) / (1.0 + mu);

			double a      = - u2 * (gamma1 + hs.d);
			double b      = gamma1 * (u2 - 1.0) + gamma2 * (u2 + 1.0);
			double c      = gamma1 - hs.d;

			double D      = b * b - 4 * a * c;

			if (D < 0.0){
				return false; // no intersection
			}

			// calculate roots a'la Numerical Recipes
			double SGN;
			if (b < 0.0){
				SGN = -1.0;
			} else {
				if (b > 0){
					SGN = 1.0;
				} else {
					SGN = 0.0;
				}
			}
			double q      = -0.5 * (b + (SGN * Math.Sqrt(D)));
			double root1 = -999.0, root2 = -999.0;
			int i = 0;

			if ( a > Cartesian.Epsilon || a < -Cartesian.Epsilon ) { root1 = q / a; i++; }
			if ( q > Cartesian.Epsilon || q < -Cartesian.Epsilon ) { root2 = c / q; i++; }

			// Check whether the roots lie within [0,1]. If not, the intersection
			// is outside the edge.

			if (i == 0) {
				return false; // no solution
			}
			// if i > 0, then root1 is assigned a value;
			if (root1 >= 0.0 && root1 <= 1.0){
				return true;
			}
			// If i == 2, then root2 was assigned a value;
			if (i == 2 && ((root1 >= 0.0 && root1 <= 1.0) ||
				(root2 >= 0.0 && root2 <= 1.0))){
				return true;
			}
			return false;
		} // METHOD
Esempio n. 12
0
		/// <summary>
		/// Test if edges intersect with halfspace. This problem
		/// is solved by a quadratic equation. Return true if there is
		///	an intersection.
		/// </summary>
		/// <param name="v0"></param>
		/// <param name="v1"></param>
		/// <param name="v2"></param>
		/// <returns></returns>
		private bool testEdge(Cartesian v0, Cartesian v1, Cartesian v2){
			Halfspace hs;
			for(int i = 0; i < _halfspaces.Count; i++) {
				hs = (Halfspace) _halfspaces[i];
				if ( hs.sign < 0 ) {  // test only 'holes'
					if ( eSolve(v0, v1, i) ) return true;
					if ( eSolve(v1, v2, i) ) return true;
					if ( eSolve(v2, v0, i) ) return true;
				}
			}
			return false;
		}
Esempio n. 13
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]);
		}
Esempio n. 14
0
		private bool testHole(Cartesian v0, Cartesian v1, Cartesian v2){
			Cartesian r1, r2, r3;
			bool test = false;
			Halfspace hs;
			r1 = new Cartesian();
			r2 = new Cartesian();
			r3 = new Cartesian();
			for(int i = 0; i < _halfspaces.Count; i++) {
				hs = (Halfspace) _halfspaces[i];
				if ( hs.sign < 0) {  
					// test only 'holes'
					// If (a ^ b * c) < 0, vectors abc point clockwise.
					// -> center c not inside triangle, since vertices a,b are ordered
					// counter-clockwise. The comparison here is the other way
					// round because c points into the opposite direction as the hole
					//
					// The old code said this:
					//					if ( ( ( v0 ^ v1 ) *
					//						_halfspaces[i].a_) > 0.0L ) continue;
					//					if ( ( ( v1 ^ v2 ) *
					//						_halfspaces[i].a_) > 0.0L ) continue;
					//					if ( ( ( v2 ^ v0 ) *
					//						_halfspaces[i].a_) > 0.0L ) continue;
					
					r1.assign(v0);
					r1.crossMe(v1);
					if ( r1.dot( hs.sv) > 0.0) continue;

					r1.assign(v1);
					r1.crossMe(v2);
					if ( r1.dot( hs.sv) > 0.0) continue;

					r1.assign(v2);
					r1.crossMe(v0);
					if ( r1.dot( hs.sv) > 0.0) continue;
					test = true;
					break;
				}
			}
			return test;
		}
Esempio n. 15
0
		/// <summary>
		/// This test fails if the vertex v is inside any halfspace
		/// in this convex. In other words, it succeeds if v is
		/// not inside any of them
		/// </summary>
		/// <param name="v">vertex to test</param>
		/// <returns></returns>
		private bool isVertexOutsideAllHalfspaces(Cartesian v) {
			Halfspace hs;
			for ( int i = 0; i < _halfspaces.Count; i++){
				hs = (Halfspace) _halfspaces[i];
				if ( v.dot(hs.sv)  < hs.d ){
					return false;
				}
			}
			return true;
		}
Esempio n. 16
0
		/// <summary>
		/// Copy creator
		/// </summary>
		/// <param name="v">Another Cartesian</param>
		public Cartesian (Cartesian v){
			_x = v.x;
			_y = v.y;
			_z = v.z;
		}
Esempio n. 17
0
		/// <summary>
		/// Test if other Cartesian is "close enough" to this.
		/// The test is based on the magnitude of the 
		/// difference between this vector and
		/// the given other Cartesian. Test succeeds if the
		/// difference is Epsilon or less.
		/// </summary>
		/// <param name="a">The other Cartesian</param>
		/// <returns>true if the other cartesian is close enough</returns>
		public bool Equivalent(Cartesian a){
			double dx, dy, dz, diff;
			dx = this._x - a._x;
			dy = this._y - a._y;
			dz = this._z - a._z;
			diff = dx * dx + dy * dy + dz * dz;
			return (diff <= Epsilon2);
		}
Esempio n. 18
0
		/// <summary>
		/// Test for other positive constraints that do
		//  not intersect with an edge. Return its index
		/// </summary>
		/// <param name="v0"></param>
		/// <param name="v1"></param>
		/// <param name="v2"></param>
		/// <returns>The index of a positive constraint which does not interspect with an edge</returns>
		private int testOtherPosNone(Cartesian v0, Cartesian v1, Cartesian v2){
			int i = 0;
			while ( i < _halfspaces.Count && ((Halfspace) _halfspaces[i]).sign == Halfspace.Sign.Positive){
				if ( !testEdgeConstraint(v0, v1, v2, i)){
					return i;
				}
				i++;
			}
			return -1;
		}
Esempio n. 19
0
		/// <summary>
		/// Compute dot product of two given vectors
		/// </summary>
		/// <param name="u">First (Cartesian) vector</param>
		/// <param name="v">Second (Cartesian) vector</param>
		/// <returns>The dot product</returns>
		public static double dot(Cartesian u, Cartesian v){
			return u.x*v.x + u.y*v.y + u.z*v.z;
		}
Esempio n. 20
0
		/// <summary>
		/// Look if a constraint is inside the triangle
		/// </summary>
		/// <param name="v0"></param>
		/// <param name="v1"></param>
		/// <param name="v2"></param>
		/// <param name="i"></param>
		/// <returns>true if the constraint is inside the triage</returns>
		private bool testConstraintInside(	
			Cartesian v0, Cartesian v1, Cartesian v2, int i){
			Halfspace hs;
			hs = (Halfspace) _halfspaces[i];
			return testVectorInside(v0, v1, v2, hs.sv);
		}
Esempio n. 21
0
		/// <summary>
		/// Make a new instance of Cartesian
		/// the contents of which is a vector obtained by adding
		///	this to another Cartesian.
		/// </summary>
		/// <param name="that">The other Cartesian</param>
		/// <returns>The sum as a new instance of a Cartesian</returns>
		public Cartesian add(Cartesian that){
			return new Cartesian(
				_x + that._x,
				_y + that._y,
				_z + that._z);
		}
Esempio n. 22
0
		/// <summary>
		/// Look if a vector is inside the triangle 
		/// returns true if vector is inside
		/// </summary>
		/// <param name="v0"></param>
		/// <param name="v1"></param>
		/// <param name="v2"></param>
		/// <param name="v"></param>
		/// <returns>true if vector is inside the triangle</returns>
		private bool testVectorInside( // SUSPECT
			Cartesian v0, Cartesian v1, Cartesian v2, Cartesian v){

			// If (a ^ b * c) < 0, vectors abc point clockwise.
			// -> center c not inside triangle, since vertices are ordered
			// counter-clockwise.
			Cartesian c01 = new Cartesian(v0);
			Cartesian c12 = new Cartesian(v1);
			Cartesian c20 = new Cartesian(v2);
			c01.crossMe(v1);
			c12.crossMe(v2);
			c20.crossMe(v0);
			//			if (((( v0 ^ v1 ) * v) < 0 ) ||
			//				( (( v1 ^ v2 ) * v) < 0 ) ||
			//				( (( v2 ^ v0 ) * v) < 0 ) )
			//				return false;
			//			return true;
			if (c01.dot(v) < 0)
				return false;
			if (c12.dot(v) < 0)
				return false;
			if (c20.dot(v) < 0)
				return false;
			return true;
		}
Esempio n. 23
0
		/// <summary>
		/// Add another cartesian to this.
		/// </summary>
		/// <param name="that">The other Cartesian</param>
		public void addMe(Cartesian that){
			_x += that._x;
			_y += that._y;
			_z += that._z;
		}
Esempio n. 24
0
		/// <summary>
		/// This is the main test of a triangle vs a Convex.
		/// </summary>
		/// <param name="index"></param>
		private void testTrixel(int index){
			Int64 hid;
			Cartesian v0, v1, v2;
			double[] fa, fb, fc;
			fa = new double[3];
			fb = new double[3];
			fc = new double[3];
			 
			//
			// Compute the vertices of
			// S0, S1, ... , N3
			//
			// Wee need to ask HtmTrixel for the initial
			// values of v0,...,v2 for HID tid;
			hid = 8 + index;
			// if you consider letting addlevel be zero,
			// then this top level trixel must be tested
			// too.
			_htm.level0vertices(index, fa, fb, fc);
			v0 = new Cartesian(fa[0], fa[1], fa[2]);
			v1 = new Cartesian(fb[0], fb[1], fb[2]);
			v2 = new Cartesian(fc[0], fc[1], fc[2]);
			if (_addlevel > 0){
				testPartial(_minlevel, _addlevel, hid, v0, v1, v2, 0); // Used to die here... no more
			} 
		}
Esempio n. 25
0
		/// <summary>
		/// Subtract another vector from this one.
		/// </summary>
		/// <param name="that">The other vector</param>
		public void subMe(Cartesian that){
			_x -= that._x;
			_y -= that._y;
			_z -= that._z;
		}
Esempio n. 26
0
		/// <summary>
		/// Make a halfspace with parameters (V, D)
		/// 
		/// It is not necessary that the directional vector, though normal
		///	to the cutting plane, by definition, be a normal vector.
		/// </summary>
		/// <param name="v">The cutting plane's normal vector</param>
		/// <param name="d">The distance of the cutting plane along the normal
		/// vector's direction. Can be negative.</param>
		public Halfspace(Cartesian v, double d) {
			init();
			if (d < -1.0) _D = -1.0;
			else if (d > 1.0) _D = 1.0;
			else _D = d;
			_SV.assign(v);
			_SV.normalizeMeSafely();
			if (_D < -SpatialVector.Epsilon) {
				_sign = Sign.Negative;
			} else if (_D >= SpatialVector.Epsilon) {
				_sign = Sign.Positive;
			} else {
				_sign = Sign.Zero;
			}
			_hangle = Math.Acos(_D);
		}
Esempio n. 27
0
		/// <summary>
		/// Perform cross prodcut of this and another
		/// vector. Replaced with the result.
		/// </summary>
		/// <param name="that">The other vector</param>
		public void crossMe(Cartesian that){
			double tx, ty, tz;
			tx = _y*that.z - _z*that.y;
			ty = _z*that.x - _x*that.z;
			tz = _x*that.y - _y*that.x;
			_x = tx;
			_y = ty;
			_z = tz;
		}
Esempio n. 28
0
		/// <summary>
		/// Test whether or not point described by vector v is inside
		/// this halfspace
		/// </summary>
		/// <param name="v">A point</param>
		/// <returns>true if the specified point described by v is inside this halfspace</returns>
		public bool contains(Cartesian v) {
			
			// v is inside the halfspace, if the angle between v and
			// the direction vector is smaller than the cone half-angle.
			// Note that _D = cos(half-angle)
			//
			return (v.dot(_SV.x, _SV.y, _SV.z) >= _D);
		}
Esempio n. 29
0
		/// <summary>
		/// Test whether or not this vector is the opposite
		/// of another vector.
		/// Opposite means same magnitude, opposite direction.
		/// </summary>
		/// <param name="that">The other vector</param>
		/// <returns>true if other vector is close enough to 
		/// being opposite, false otherwise</returns>
		public bool opposite(Cartesian that){
			if (Math.Abs(that._x + _x) > Epsilon)
				return false;
			if (Math.Abs(that._y + _y) > Epsilon)
				return false;
			if (Math.Abs(that._z + _z) > Epsilon)
				return false;
			return true;
		}
Esempio n. 30
0
		/// <summary>
		/// Get the internal angles of the trixel described by
		/// a given HID.
		/// </summary>
		/// <param name="hid">The 64-bit HID</param>
		/// <param name="t1">First internal angle</param>
		/// <param name="t2">Second internal angle</param>
		/// <param name="t3">Third internal angle</param>
		/// <returns>true if successful, false if HID is invalid</returns>
		public bool getAngles(Int64 hid, out double t1, out double t2, out double t3){
			// formula for area of spherical triangle
			// A = R^2[(t1 + t2 + t3 ) - Pi], but R=1.
			//
			Cartesian n0, n1, n2;
			double[] v0, v1, v2;
			v0 = new double[3];
			v1 = new double[3];
			v2 = new double[3];
			char[] name = new char[HtmTrixel.eMaxNameSize];
			int level = this.hid2name(name, hid);
			if (level < 0) {
				t1 = t2 = t3 = 0.0;
				return false;
			} else {

				this.name2Triangle(name, v0, v1, v2);
				//
				// Compute the plane normals for the three GC arcs
				//
				n0 = new Cartesian();
				n1 = new Cartesian();
				n2 = new Cartesian();
				Cartesian.cross(n2, v1, v0);
				Cartesian.cross(n0, v2, v1);
				Cartesian.cross(n1, v0, v2);
				n0.normalizeMe();
				n1.normalizeMe();
				n2.normalizeMe();
				t1 = Math.PI - Math.Acos(Cartesian.dot(n0, n1));
				t2 = Math.PI - Math.Acos(Cartesian.dot(n1, n2));
				t3 = Math.PI - Math.Acos(Cartesian.dot(n2, n0));
			}
			return true	;
		}