/* * 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 {
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; }