Beispiel #1
0
/*
 *	 dooper() will execute a constant operation in a node and return
 *	 the node to be the result of the operation.
 */
static EXPR *dooper P1 (EXPR *, ep)
{
    EXPRTYPE type = ep->nodetype;

    ep->nodetype = ep->v.p[0]->nodetype;
    switch (ep->v.p[0]->nodetype) {
#ifdef FLOAT_SUPPORT
#ifndef FLOAT_BOOTSTRAP
	RVAL    f;
#endif	/* FLOAT_BOOTSTRAP */

    case en_fcon:
#ifndef FLOAT_BOOTSTRAP
	FASSIGN (f, ep->v.p[0]->v.f);
	switch (type) {
	case en_uminus:
	    FASSIGN (ep->v.f, f);
	    FNEG (ep->v.f);
	    break;
	case en_test:
	    ep->v.i = FTST (f) ? (IVAL) 1 : (IVAL) 0;
	    ep->nodetype = en_icon;
	    break;
	case en_not:
	    ep->v.i = FTST (f) ? (IVAL) 0 : (IVAL) 1;
	    ep->nodetype = en_icon;
	    break;
	case en_cast:
	    if (is_real_floating_type (ep->etp)) {
		ep->v.f = f;
	    } else if (is_bool (ep->etp)) {
		ep->v.u = (UVAL) (f ? 1 : 0);
		ep->nodetype = en_icon;
	    } else {
		FTOL (ep->v.i, f);
		ep->v.i = strip_icon (ep->v.i, ep->etp);
		ep->nodetype = en_icon;
	    }
	    break;
	case en_add:
	    FADD3 (ep->v.f, f, ep->v.p[1]->v.f);
	    break;
	case en_sub:
	    FSUB3 (ep->v.f, f, ep->v.p[1]->v.f);
	    break;
	case en_mul:
	    FMUL3 (ep->v.f, f, ep->v.p[1]->v.f);
	    break;
	case en_div:
	    if (FTST (ep->v.p[1]->v.f)) {
		FDIV3 (ep->v.f, f, ep->v.p[1]->v.f);
	    } else {
		ep->nodetype = en_div;
	    }
	    break;
	case en_eq:
	    ep->v.i = (IVAL) FEQ (f, ep->v.p[1]->v.f);
	    ep->nodetype = en_icon;
	    break;
	case en_ne:
	    ep->v.i = (IVAL) FNE (f, ep->v.p[1]->v.f);
	    ep->nodetype = en_icon;
	    break;
	case en_land:
	    ep->v.i = (IVAL) (FTST (f) && FTST (ep->v.p[1]->v.f));
	    ep->nodetype = en_icon;
	    break;
	case en_lor:
	    ep->v.i = (IVAL) (FTST (f) || FTST (ep->v.p[1]->v.f));
	    ep->nodetype = en_icon;
	    break;
	case en_lt:
	    ep->v.i = (IVAL) FLT (f, ep->v.p[1]->v.f);
	    ep->nodetype = en_icon;
	    break;
	case en_le:
	    ep->v.i = (IVAL) FLE (f, ep->v.p[1]->v.f);
	    ep->nodetype = en_icon;
	    break;
	case en_gt:
	    ep->v.i = (IVAL) FGT (f, ep->v.p[1]->v.f);
	    ep->nodetype = en_icon;
	    break;
	case en_ge:
	    ep->v.i = (IVAL) FGE (f, ep->v.p[1]->v.f);
	    ep->nodetype = en_icon;
	    break;
	default:
	    CANNOT_REACH_HERE ();
	    break;
	}
	break;
	
#endif /* FLOAT_BOOTSTRAP */
#endif /* FLOAT_SUPPORT */
    case en_icon:
	if (is_unsigned_type (ep->v.p[0]->etp)) {
	    UVAL    u = ep->v.p[0]->v.u;

	    switch (type) {
	    case en_uminus:
		/*
		 *       unary minus on an unsigned is normally a mistake so we must
		 *       fool the compiler into not giving a warning.
		 */
		ep->v.u = (UVAL) (-(IVAL) u);
		break;
	    case en_test:
		ep->v.u = (u ? (UVAL) 1 : (UVAL) 0);
		break;
	    case en_not:
		ep->v.u = (u ? (UVAL) 0 : (UVAL) 1);
		break;
	    case en_compl:
		ep->v.u = (UVAL) strip_icon ((IVAL) ~u, ep->etp);
		break;
	    case en_cast:
		if (is_bool (ep->etp)) {
		    ep->v.u = (UVAL) (u ? 1 : 0);
#ifdef FLOAT_SUPPORT
		} else if (is_real_floating_type (ep->etp)) {
		    ep->nodetype = en_fcon;
		    UTOF (ep->v.f, u);
		    break;
#endif /* FLOAT_SUPPORT */
		} else {
		    ep->v.u = (UVAL) strip_icon ((IVAL) u, ep->etp);
		}
		break;
	    case en_add:
		ep->v.u = u + ep->v.p[1]->v.u;
		break;
	    case en_sub:
		ep->v.u = u - ep->v.p[1]->v.u;
		break;
	    case en_mul:
		ep->v.u = u * ep->v.p[1]->v.u;
		break;
	    case en_div:
		if (ep->v.p[1]->v.u == (UVAL) 0) {
		    ep->nodetype = en_div;
		} else {
		    ep->v.u = u / ep->v.p[1]->v.u;
		}
		break;
	    case en_mod:
		if (ep->v.p[1]->v.u == (UVAL) 0) {
		    ep->nodetype = en_mod;
		} else {
		    ep->v.u = u % ep->v.p[1]->v.u;
		}
		break;
	    case en_and:
		ep->v.u = u & ep->v.p[1]->v.u;
		break;
	    case en_or:
		ep->v.u = u | ep->v.p[1]->v.u;
		break;
	    case en_xor:
		ep->v.u = u ^ ep->v.p[1]->v.u;
		break;
	    case en_eq:
		ep->v.u = (UVAL) (u == ep->v.p[1]->v.u);
		break;
	    case en_ne:
		ep->v.u = (UVAL) (u != ep->v.p[1]->v.u);
		break;
	    case en_land:
		ep->v.u = (UVAL) (u && ep->v.p[1]->v.u);
		break;
	    case en_lor:
		ep->v.u = (UVAL) (u || ep->v.p[1]->v.u);
		break;
	    case en_lt:
		ep->v.u = (UVAL) (u < ep->v.p[1]->v.u);
		break;
	    case en_le:
		ep->v.u = (UVAL) (u <= ep->v.p[1]->v.u);
		break;
	    case en_gt:
		ep->v.u = (UVAL) (u > ep->v.p[1]->v.u);
		break;
	    case en_ge:
		ep->v.u = (UVAL) (u >= ep->v.p[1]->v.u);
		break;
	    case en_lsh:
		ep->v.u = u << ep->v.p[1]->v.u;
		break;
	    case en_rsh:
		ep->v.u = u >> ep->v.p[1]->v.u;
		break;
	    default:
		CANNOT_REACH_HERE ();
		break;
	    }
	} else {
Beispiel #2
0
	bool Span::OnSpan(const Point& p, double* t)const {
		// FAST OnSpan test - assumes that p lies ON the unbounded span
#if _DEBUG
		if(this->returnSpanProperties == false) {
			FAILURE(L"OnSpan - properties no set, incorrect calling code");
		}
#endif
#if 0
		if(NullSpan) {
			*t = 0.0;
			return (p == p0);
		}

		if(p == p0) {
			*t = 0.0;
			return true;
		}

		if(p == p1) {
			*t = 1.0;
			return true;
		}
#endif
		bool ret;
//		if(p == this->p0 || p == this->p1) return true;

		if(dir == LINEAR) {
#if 1
#if _DEBUG
			// check p is on line
			CLine cl(*this);
			double d = fabs(cl.Dist(p));
			if( d > geoff_geometry::TOLERANCE) {
				FAILURE(L"OnSpan - point not on linear span, incorrect calling code");
			}
#endif
#endif
			Vector2d v0(p0, p);
			*t = vs * v0;
//			ret = (*t > - geoff_geometry::TOLERANCE && *t < length + geoff_geometry::TOLERANCE);

			*t = *t / length;
			ret = (*t >= 0 && *t <= 1.0 );

		}
		else {
			// true if p lies on arc span sp (p must be on circle of span)
#if 1
#if _DEBUG
			// check that p lies on the arc
			double d = p.Dist(pc);
			if(FNE(d, radius, geoff_geometry::TOLERANCE)) {
				FAILURE(L"OnSpan - point not on circular span, incorrect calling code");
			}

#endif
#endif
#if 0	// alt method (faster, but doesn't provide t)
			Vector2d v0(p0, p);
			Vector2d v1(p0, p1);

			// check angle to point from start
			double cp;
			ret = ((cp = (dir * (v0 ^ v1))) > 0);
			*t = 0.0;// incorrect !!!
#else
			Vector2d v = ~Vector2d(pc, p);
			v.normalise();
			if(dir == CW) v = -v;

			double ang = IncludedAngle(vs, v, dir);
			*t = ang / angle;
			ret = (*t >= 0 && *t <= 1.0);
#endif
		}

		return ret;
	}