Ejemplo n.º 1
0
		public Polygon.Error add(double[] x, double[] y, double[] z, int len){
			
			bool DIRECTION = false;
			bool FIRST_DIRECTION = false;
			// The constraint we have for each side is a 0-constraint (great circle)
			// passing through the 2 corners. Since we are in counterclockwise order,
			// the vector product of the two successive corners just gives the correct
			// constraint.
			// 
			// Polygons should be counterclockwise
			// Polygons are assumed to be convex, otherwise windingerror is
			// computed wrong.
			int ix;
			Cartesian v = new Cartesian();
			Convex cvx = 
				new Convex(Convex.Mode.Normal);
			int i;

			/* PASS 1: check for winding error */

			for(i = 0; i < len; i++) {
				// Keep track of winding direction. Should be positive
				// that is, CCW.
				ix = (i==len-1 ? 0 : i+1); 
				if (i>0){
					// test third corner against the constraint just formed
					// v is computed in the previous iteration
					// Look at a corner dot v

					if (v.dot(x[ix], y[ix], z[ix]) < Cartesian.Epsilon) {
						DIRECTION = true;
						if (i == 1) {
							FIRST_DIRECTION = true;
						}
						// break; 		// Move to pass 2
					} else {
						DIRECTION = false;
						if (i == 1) {
							FIRST_DIRECTION = false;
						}
					}
					if (i > 1) {
						if (DIRECTION != FIRST_DIRECTION) {
							// C++: must clea up new Cartesian and convex
							// or better yet, do no allocate on top until you know
							// you need it
							return Polygon.Error.errBowtieOrConcave; // BOWTie error
						}
					}
				}
				// v = corners[i] ^ corners[ i == len-1 ? 0 : i + 1];
				v.assign(x[i], y[i], z[i]);
				v.crossMe(x[ix], y[ix], z[ix]);
				if (v.isLength(0.0, Cartesian.Epsilon)) {
					return Polygon.Error.errZeroLength;
				}
				// WARNING! if v = zerovector, then edge error!!!
			}
			/* PASS 2: build convex in either original or reverse
			   order */

			/* forward:
			   Go from 0 to len-1 by +1, cross i and i+1 (or 0)
			   reverse:
			   Go from len-1 to 0 by -1, cross i and i-1 (or len-1)
			*/
			if (DIRECTION) {
				for(i=len-1; i>=0; i--){
					// v = corners[i] ^ corners[ i == 0 ? len-1 : i-1];
					// v.normalize();
					ix = (i==0? len-1 : i-1);
					v.assign(x[i], y[i], z[i]);
					v.crossMe(x[ix], y[ix], z[ix]);
					// WARNING! if v = zerovector, then edge error!!!

					v.normalizeMe();
					Halfspace c = new Halfspace(v, 0.0);
					// SpatialConstraint c(v,0);
					cvx.add(c);
				}
			} else {
				for(i=0; i<len; i++){

					//v = corners[i] ^ corners[ i == len-1 ? 0 : i+1];
					// v.normalize();
					ix = (i==len-1 ? 0 : i+1);
					v.assign(x[i], y[i], z[i]);
					v.crossMe(x[ix], y[ix], z[ix]);
					// WARNING! if v = zerovector, then edge error!!!

					v.normalizeMe();
					Halfspace c = new Halfspace(v, 0.0);
					cvx.add(c);
				}
			}
			_reg.add(cvx);
			return Polygon.Error.Ok;
		}