double carve::triangulate::detail::vertex_info::triScore(const vertex_info *p, const vertex_info *v, const vertex_info *n) { // different scoring functions. #if 0 bool convex = isLeft(p, v, n); if (!convex) return -1e-5; double a1 = carve::geom2d::atan2(p->p - v->p) - carve::geom2d::atan2(n->p - v->p); double a2 = carve::geom2d::atan2(v->p - n->p) - carve::geom2d::atan2(p->p - n->p); if (a1 < 0) a1 += M_PI * 2; if (a2 < 0) a2 += M_PI * 2; return std::min(a1, std::min(a2, M_PI - a1 - a2)) / (M_PI / 3); #endif #if 1 // range: 0 - 1 double a, b, c; bool convex = isLeft(p, v, n); if (!convex) return -1e-5; a = (n->p - v->p).length(); b = (p->p - n->p).length(); c = (v->p - p->p).length(); if (a < 1e-10 || b < 1e-10 || c < 1e-10) return 0.0; return std::max(std::min((a+b)/c, std::min((a+c)/b, (b+c)/a)) - 1.0, 0.0); #endif }
int tedop::SweepLine::intersect(plysegment* seg1, plysegment* seg2) { // check both segments exists if ((NULL == seg1) || (NULL == seg2)) return false; // check for consecuitive polygon edges unsigned edge1 = seg1->edge; unsigned edge2 = seg2->edge; if ((((edge1+1) % _numv) == edge2) || (((edge2+1) % _numv) == edge1)) return false; // Now test for intersection point exsistence float lsign, rsign; lsign = isLeft(seg1->lP, seg1->rP, seg2->lP); rsign = isLeft(seg1->lP, seg1->rP, seg2->rP); //check that both s2 endpoints are on the same side of s1 if (lsign*rsign > 0) return false; // Check the exception with coinciding segments if ((0 == lsign*rsign) && coincideOK(seg1, seg2, lsign, rsign)) return false; lsign = isLeft(seg2->lP, seg2->rP, seg1->lP); rsign = isLeft(seg2->lP, seg2->rP, seg1->rP); //check that both s1 endpoints are on the same side of s2 if (lsign*rsign > 0) return false; // Check the exception with coinciding segments if ((0 == lsign*rsign) && coincideOK(seg2, seg1, lsign, rsign)) return false; // at this point - the only possibility is that they intersect return true; }
bool IsPointInsidePolygon( const CVector2< int >& point, const std::vector< CVector2< int > >& polygon ) { int wn = 0; // the winding number counter // std::vector<CPoint *>::iterator it; unsigned int i = 0; // loop through all edges of the polygon for( i = 0; i < polygon.size()-1; i++ ) // edge from V[i] to V[i+1] { if( polygon[ i ].y <= point.y ) { // start y <= pt->y if( polygon[ i + 1 ].y > point.y ) // an upward crossing if( isLeft( polygon[ i ], polygon[ i + 1 ], point ) > 0 ) // P left of edge ++wn; // have a valid up intersect } else { // start y > P.y (no test needed) if( polygon[ i + 1].y <= point.y ) // a downward crossing if( isLeft( polygon[ i ], polygon[ i + 1 ], point ) < 0 ) // P right of edge --wn; // have a valid down intersect } } if ( wn==0 ) return false; return true; }
// Specify the residual. This is where the ODE system and boundary // conditions are specified. The solver will attempt to find a solution // x so that this function returns 0 for all n and j. virtual doublereal residual(doublereal* x, size_t n, size_t j) { // if n = 0, return the residual for the first ODE if (n == 0) { if (isLeft(j)) { // here we specify zeta(0) = 0 return zeta(x,j); } else // this implements d(zeta)/dz = u { return (zeta(x,j) - zeta(x,j-1))/(z(j)-z(j-1)) - u(x,j); } } // if n = 1, then return the residual for the second ODE else { if (isLeft(j)) { // here we specify u(0) = 0 return u(x,j); } else if (isRight(j)) { // and here we specify u(L) = 1 return u(x,j) - 1.0; } else // this implements the 2nd ODE { return cdif2(x,1,j) + 0.5*zeta(x,j)*centralFirstDeriv(x,1,j); } } }
Intersection detecteTypeIntersection() { Intersection intersectionType = inter_none; if ( isCenter() && ( isLeft() || isRight() )) { // Permettra un meilleur redressement par la suit enregistrerDernierCapteurActif( dernierCapteurActif, dernierCapteurCoteActif ); // Teste si une ligne est détectée à gauche // cas possibles: cross, tBase, tRight, lLeft. if( isLeft() ) { trouverTypeIntersectionPourUnCote( intersectionType, capteur_gauche, capteur_droit ); } // Teste si une ligne est détectée à droite // cas possibles: cross, tBase, tLeft, lRight. else if( isRight() ) { trouverTypeIntersectionPourUnCote( intersectionType, capteur_droit, capteur_gauche ); } } return intersectionType; }
int simIsPointInPolyWind(cdPoint* poly, int n, int x, int y) { int i, i1, wn = 0; /* the winding number counter */ for (i = 0; i < n; i++) { i1 = (i+1)%n; /* next point(i+1), next of last(n-1) is first(0) */ if (poly[i].y <= y) { if (poly[i1].y > y) /* an upward crossing */ if (isLeft(poly[i], poly[i1], x, y) > 0) /* P left of edge */ ++wn; /* have a valid up intersect */ } else { if (poly[i1].y <= y) /* a downward crossing */ if (isLeft(poly[i], poly[i1], x, y) < 0) /* P right of edge */ --wn; /* have a valid down intersect */ } } return wn; }
bool PolygonInterior(const FlatGeoPoint &P, SearchPointVector::const_iterator begin, SearchPointVector::const_iterator end) { if (std::distance(begin, end) < 3) return false; int wn = 0; // the winding number counter // loop through all edges of the polygon for (auto i = begin, next = std::next(i); next != end; i = next, next = std::next(i)) { // edge from current to next if (i->GetFlatLocation().y <= P.y) { // start y <= P.y if (next->GetFlatLocation().y > P.y) // an upward crossing if (isLeft(i->GetFlatLocation(), next->GetFlatLocation(), P) > 0) // P left of edge // have a valid up intersect ++wn; } else { // start y > P.y (no test needed) if (next->GetFlatLocation().y <= P.y) // a downward crossing if (isLeft(i->GetFlatLocation(), next->GetFlatLocation(), P) < 0) // P right of edge // have a valid down intersect --wn; } } return wn != 0; }
void AdvHuffman::switchNode(int A, int B) /* Menukar 2 buah node pada pohon yang sama */ { int temp = A; int parentA= TabNode[A].getParent(); int parentB= TabNode[B].getParent(); if (isLeft(A) && (isRight(B))){ TabNode[parentA].setLeft(B); TabNode[parentB].setRight(temp); TabNode[temp].setParent(parentB); TabNode[B].setParent(parentA); } else if (isLeft(A) && (isLeft(B))){ TabNode[parentA].setLeft(B); TabNode[parentB].setLeft(temp); TabNode[temp].setParent(parentB); TabNode[B].setParent(parentA); } else if (isRight(A) && (isLeft(B))){ TabNode[parentA].setRight(B); TabNode[parentB].setLeft(temp); TabNode[temp].setParent(parentB); TabNode[B].setParent(parentA); } else { TabNode[parentA].setRight(B); TabNode[parentB].setRight(temp); TabNode[temp].setParent(parentB); TabNode[B].setParent(parentA); } }
/*! The method is using isLeft() function to do the job. Segments that belong to the same polygon are not checked and method returns NULL. The same result is obtained if one of the input segmens is NULL. \n In case segments intersect, the method creates and returns a new CEvent.*/ logicop::CEvent* logicop::SweepLine::intersect(plysegment* above, plysegment* below) { // check both segments exists if ((NULL == above) || (NULL == below)) return NULL; // check for polygon edges belonging to the same polygon if (above->polyNo == below->polyNo) return NULL; // Now test for intersection point exsistence float lsign, rsign, rlmul; lsign = isLeft(above->lP, above->rP, below->lP); rsign = isLeft(above->lP, above->rP, below->rP); //check that both s2 endpoints are on the same side of s1 rlmul = lsign*rsign; if (0 < rlmul) return NULL; else if (0 == rlmul) { int boza = 1; boza++; return NULL; } lsign = isLeft(below->lP, below->rP, above->lP); rsign = isLeft(below->lP, below->rP, above->rP); //check that both s1 endpoints are on the same side of s2 rlmul = lsign*rsign; if (0 < rlmul) return NULL; else if (0 == rlmul) { int boza = 1; boza++; return NULL; } // at this point - the only possibility is that they intersect // so - create a cross event return new CEvent(above,below); }
bool operator==(const Alternative& in) const { if (isLeft() != in.isLeft()) return false; if (isLeft()) return in.left() == left(); else return in.right() == right(); }
Bool m4_path_point_over(LPM4PATH _this, Float x, Float y) { u32 i, j; s32 wn; M4Point2D start, s, e, pt; M4Rect rc; M4PATH(); pt.x = x; pt.y = y; rc.x = path->min_x; rc.y = path->min_y; rc.width = path->max_x - rc.x; rc.height = path->max_y - rc.y; if (pt.x < rc.x) return 0; if (pt.y < rc.y) return 0; if (pt.x > rc.x + rc.width) return 0; if (pt.y > rc.y + rc.height) return 0; wn = 0; for (i=0; i<path->subpathlen; i++) { if (!path->subpath[i]->pointlen) continue; start = path->subpath[i]->point[0]; s = start; for (j=1; j<path->subpath[i]->pointlen; j++) { e = path->subpath[i]->point[j]; if (s.y<=pt.y) { if (e.y>pt.y) { if (isLeft(s, e, pt) > 0) wn++; } } else if (e.y<=pt.y) { if (isLeft(s, e, pt) < 0) wn--; } s = e; } /*close path if needed*/ if ((start.x != s.x) && (start.y != s.y)) { e = start; if (s.x<=pt.x) { if (e.y>pt.y) { if (isLeft(s, e, pt) > 0) wn++; } } else if (e.y<=pt.y) { if (isLeft(s, e, pt) < 0) wn--; } } } if (path->fill_mode == M4PathFillZeroNonZero) return wn ? 1 : 0; return wn%2 ? 1 : 0; }
bool operator<(const Alternative& in) const { if (isLeft() && !in.isLeft()) return false; if (!isLeft() && in.isLeft()) return true; if (isLeft()) return left() < in.left(); else return right() < in.right(); }
Tile calculateTile( const Tile origin, const Tile direction ) { return (isLeft(origin) && isLeft(direction) || isRight(origin) && isRight(direction) || isTopRow(origin) && isTopRow(direction) || isBottomRow(origin) && isBottomRow(direction)) ? eTile_Count : static_cast<Tile>(origin + (direction - eTile_Origin)); }
/* handle id, literals, and (...) */ static Expression *e1(void) { if (isLeft()) { /* ( <expression> ) */ consume(); Expression *e = expression(); if (!isRight()) { error(); } consume(); return e; } else if (isInt()) { /* 123 */ int v = getInt(); consume(); Expression *e = NEW(Expression); e->kind = eVAL; e->val = v; return e; } else if (isId()) { /* xyz */ char *id = getId(); consume(); if (isLeft()) { /* xyz ( <actuals> ) */ consume(); Expression *e = NEW(Expression); e->kind = eCALL; e->callName = id; e->callActuals = actuals(); if (!isRight()) error(); consume(); return e; } else { Expression *e = NEW(Expression); e->kind = eVAR; e->varName = id; return e; } } else { error(); return 0; } }
bool Delaunay::isInTriangle(Point& point, FHandle fh) { PointVec triangle_points; for (auto& vh : mesh.fv_range(fh)) { triangle_points.push_back(mesh.point(vh)); } bool b1 = isLeft(point, triangle_points[0], triangle_points[1]); bool b2 = isLeft(point, triangle_points[1], triangle_points[2]); bool b3 = isLeft(point, triangle_points[2], triangle_points[0]); return (b1 == b2) && (b2 == b3); }
/* fun <id> ( <formals> ) <body> */ static Fun *fun() { if (!isFun()) return 0; consume(); Fun *p = NEW(Fun); if (!isId()) error(); p->name = getId(); consume(); if (!isLeft()) error(); consume(); p->formals = formals(); if (!isRight()) error(); consume(); p->body = statement(); return p; }
void tranform(const char * exp) { int i = 0; LinkStack * stack = LinkStack_Create(); while ( exp[i] != '\0' ) { if ( isNumber(exp[i]) ) print(exp[i]); else if ( isOperator(exp[i]) ) { while (priority(exp[i]) <= priority((char)(int)LinkStack_Top(stack)) ) { print((char)(int)LinkStack_Pop(stack)); } LinkStack_Push(stack, (void*)(int)exp[i]); } else if ( isLeft(exp[i]) ) { LinkStack_Push(stack, (void*)(int)exp[i]); } else if ( isRight(exp[i]) ) { char c = 0; while ((c=(char)(int)LinkStack_Pop(stack)) != '(') print(c); } else { printf("invalid expression!\n"); break; } i++; } while ( LinkStack_Size(stack)>0 && exp[i]=='\0') print((char)(int)LinkStack_Pop(stack)); LinkStack_Destroy(stack); }
int scanner(const char *code) { int i = 0; int ret = 0; LinkStack *stack = LinkStack_Create(); while ( code[i] != '\0') { if ( isLeft(code[i]) ) LinkStack_Push(stack, (void*)(code+i)); if ( isRight(code[i]) ) { char* c = (char*)LinkStack_Pop(stack); if ( (c==NULL) || !match(*c, code[i]) ) { printf("%c does not match!\n", code[i]); ret = 0; break; } } i++; } if ( LinkStack_Size(stack)==0 && code[i]=='\0') { printf("success!\n"); ret = 1; } else { printf("failed!\n"); ret = 0; } LinkStack_Destroy(stack); return ret; }
void addNode(BinSTreeNode *rootNode, BinSTreeNode *node) { if (node == NULL) { return; } if (rootNode->str == NULL) { /* rootNode is empty! */ rootNode->str = (char*)malloc(sizeof(char)*(mystrlen(node->str)+1)); mystrcpy(rootNode->str, node->str); setNodeAsLeft(rootNode, node->left); setNodeAsRight(rootNode, node->right); node->left = NULL; node->right = NULL; deleteNode(node); } else { /* Normal addNode() */ if (isLeft(rootNode, node)) { /* node should be left of root */ if (rootNode->left == NULL) { /* There is no left child */ setNodeAsLeft(rootNode, node); if(DEBUG) printf("Add %s <- [%s%s%s]\n", node->str, CYAN, rootNode->str, DEFAULT); } else { /* search for left edge */ addNode(rootNode->left, node); } } else { /* root <= node */ if (rootNode->right == NULL) { /* There is no right child */ setNodeAsRight(rootNode, node); if(DEBUG) printf("Add [%s%s%s] -> %s\n", CYAN, rootNode->str, DEFAULT, node->str); } else { /* search for left edge */ addNode(rootNode->right, node); } } } return; }
Status scanner(char* c){ LinkStack* stack = NULL; InitStack(&stack); Status ret = FALSE; int i = 0; while(c[i] != '\0'){ elemType e; if( isLeft(c[i]) ){ Push(stack,(elemType)c[i]); } if(isRight(c[i])){ char codeOut; Pop(stack,&e); codeOut = (char)e; if(!isMatch(codeOut,c[i])){ printf("not matching %c %c\n",codeOut,c[i]); ret = FALSE; goto EXIT; } } i++; } if(StackEmpty(stack)){ ret = TRUE; }else{ ret = FALSE; } EXIT: ClearStack(&stack); return ret; }
void PaintInsideHull(vector<unsigned char>& im, const vector<CParticleF>& vch, const int* dims) { for(int y=0; y<dims[1]; ++y) { for(int x=0; x<dims[0]; ++x) { bool bOut = false; CParticleF q(x, y, 0); for(int n=0; n<vch.size(); ++n) { CParticleF p0 = vch[n]; CParticleF p1 = vch[(n+1) % vch.size()]; if(isLeft(p0, p1, q)<0) { bOut = true; break; } } if(bOut == false) { SetData2(im, x, y, dims[0], dims[1], (unsigned char)1); } } } }
// Determina se no ponto p do polígono o triangulo formado com os vértices vizinhos é uma orelha int checkEar(list<int> & currPoly, list<int>::iterator & pIterator, const vector<Point2D> & p){ // Obtém ponto anterior a p no polígono atual list<int>::iterator prevIterator = getPrevIterator(currPoly, pIterator); // Obtém ponto seguinte a p no polígono atual list<int>::iterator nextIterator = getNextIterator(currPoly, pIterator); // Determina índice dos pontos do triângulo do teste de orelha int p0 = *prevIterator; int p1 = *pIterator; int p2 = *nextIterator; // Se p2 está a direita de p0p1 então a diagonal p0p2 é externa a currPoly, portanto não é uma orelha if(!isLeft(p[p0], p[p1], p[p2])) return 0; // Determina se algum ponto do polígono diferente de p0, p1 e p2 é interno ao triângulo formado por estes pontos list<int>::iterator currIterator = getNextIterator(currPoly, nextIterator); while(currIterator != prevIterator){ int currP = *currIterator; // Se o ponto atual está dentro do triângulo p0p1p2 então o mesmo não é uma orelha if(inTriangle(p[p0], p[p1], p[p2], p[currP])){ return 0; } currIterator = getNextIterator(currPoly, currIterator); } // Se não existiu nenhum ponto dentro do triầngulo p0p1p2 então o mesmo é uma orelha return 1; }
/* 1/radius of the circle passing thought 3 points */ double getCurvatureCircle(Point P1, Point P2, Point P3) { if(P1==P2 || P2==P3 || P1==P3) return 0; double a,b,c,p,pa,pb,pc,S; a = distancePoints(P1,P2); b = distancePoints(P2,P3); c = distancePoints(P3,P1); //cout<<"a = "<<a<<" b = "<<b<<" c = "<<c<<endl; p=a+b+c; pa=b+c-a; pb=a+c-b; pc=a+b-c; S=sqrt(p*pa*pb*pc); double radius, curvature=0; if (S!=0) { radius=a*b*c/S; curvature=(double) 1/radius; //if(isLeft(P2,P3,P1)<0) curvature=-curvature; if(isLeft(P1,P2,P3)<0) curvature=-curvature; } //else // curvature = 1e-6; return curvature; }
void Creep::draw(sf::RenderWindow &window) { if (tileSet_) { sf::Sprite creepSprite = tileSet_->getSpriteById(1); sf::Vector2f position = getPosition(); int drawnSize = TileSet::getDrawnSize(); creepSprite.setOrigin(drawnSize/2.f,drawnSize/2.f); position.x += drawnSize/2.f; position.y += drawnSize/2.f; creepSprite.setPosition(position); int goingTo = paths_.getNextByID(comingFrom_); if (isAbove(comingFrom_,goingTo)) { creepSprite.setRotation(180); }else if (isBelow(comingFrom_,goingTo)) { creepSprite.setRotation(0); }else if (isLeft(comingFrom_,goingTo)) { creepSprite.setRotation(90); }else if (isRight(comingFrom_,goingTo)) { creepSprite.setRotation(270); } window.draw(creepSprite); } return; }
void LaptopButton::reset(unsigned long changed) { if (changed&DecorationReset || changed&ManualReset || changed&SizeChange || changed&StateChange) { switch (type() ) { case CloseButton: setBitmap(close_bits); break; case HelpButton: setBitmap(question_bits); break; case MinButton: setBitmap(iconify_bits); break; case MaxButton: if (isChecked() ) { setBitmap(isLeft() ? l_minmax_bits : r_minmax_bits); } else { setBitmap(maximize_bits); } break; case OnAllDesktopsButton: setBitmap( isChecked() ? unsticky_bits : sticky_bits ); break; default: setBitmap(0); break; } this->update(); } }
void QuartzButton::drawButton(QPainter *p) { // Never paint if the pixmaps have not been created if (!quartz_initialized) return; QColor c; if (isLeft() ) c = KDecoration::options()->color(KDecoration::ColorTitleBar, decoration()->isActive()).light(130); else c = KDecoration::options()->color(KDecoration::ColorTitleBlend, decoration()->isActive()); // Fill the button background with an appropriate color p->fillRect(0, 0, width(), height(), c ); // If we have a decoration bitmap, then draw that // otherwise we paint a menu button (with mini icon), or a onAllDesktops button. if( deco ) { int xOff = (width()-10)/2; int yOff = (height()-10)/2; p->setPen( Qt::black ); p->drawPixmap(isDown() ? xOff+2: xOff+1, isDown() ? yOff+2 : yOff+1, *deco); p->setPen( KDecoration::options()->color(KDecoration::ColorButtonBg, decoration()->isActive()).light(150) ); p->drawPixmap(isDown() ? xOff+1: xOff, isDown() ? yOff+1 : yOff, *deco); } else { QPixmap btnpix; int Offset = 0; if (type() == OnAllDesktopsButton) { if (isDown()) Offset = 1; // Select the right onAllDesktops button to paint if (decoration()->isActive()) btnpix = isOn() ? *pinDownPix : *pinUpPix; else btnpix = isOn() ? *ipinDownPix : *ipinUpPix; } else btnpix = decoration()->icon().pixmap( QIconSet::Small, QIconSet::Normal); // Shrink the miniIcon for tiny titlebars. if ( height() < 16) { QPixmap tmpPix; // Smooth scale the image tmpPix.convertFromImage( btnpix.convertToImage().smoothScale(height(), height())); p->drawPixmap( 0, 0, tmpPix ); } else { Offset += (height() - 16)/2; p->drawPixmap( Offset, Offset, btnpix ); } } }
static void gf_subdivide_cubic_hit_test(Fixed h_x, Fixed h_y, Fixed x0, Fixed y0, Fixed x1, Fixed y1, Fixed x2, Fixed y2, Fixed x3, Fixed y3, s32 *wn) { GF_Point2D s, e, pt; Fixed x_m, y_m, xa1, ya1, xa2, ya2, xb1, yb1, xb2, yb2, y_min, y_max; /*if hit line doesn't intersects control box abort*/ y_min = MIN(y0, MIN(y1, MIN(y2, y3))); y_max = MAX(y0, MAX(y1, MAX(y2, y3))); if ((h_y<y_min) || (h_y>y_max) ) return; /*if vert diff between end points larger than 1 pixels, subdivide (we need pixel accuracy for is_over)*/ if (y_max - y_min > FIX_ONE) { xa1 = (x0 + x1) / 2; ya1 = (y0 + y1) / 2; xa2 = (x0 + 2 * x1 + x2) / 4; ya2 = (y0 + 2 * y1 + y2) / 4; xb1 = (x1 + 2 * x2 + x3) / 4; yb1 = (y1 + 2 * y2 + y3) / 4; xb2 = (x2 + x3) / 2; yb2 = (y2 + y3) / 2; x_m = (xa2 + xb1) / 2; y_m = (ya2 + yb1) / 2; gf_subdivide_cubic_hit_test(h_x, h_y, x0, y0, xa1, ya1, xa2, ya2, x_m, y_m, wn); gf_subdivide_cubic_hit_test(h_x, h_y, x_m, y_m, xb1, yb1, xb2, yb2, x3, y3, wn); return; } s.x = x0; s.y = y0; e.x = x3; e.y = y3; pt.x = h_x; pt.y= h_y; if (s.y<=pt.y) { if (e.y>pt.y) { if (isLeft(s, e, pt) > 0) (*wn)++; } } else if (e.y<=pt.y) { if (isLeft(s, e, pt) < 0) (*wn)--; } }
void ImageRotateOverlay::updateButton(const QModelIndex& index) { const QRect rect = m_view->visualRect(index); const int gap = 5; const int x = rect.right() - 2*gap - (isLeft() ? KIconLoader::SizeSmall*3 + 2 : KIconLoader::SizeSmall*2 +2); const int y = rect.top() + gap; button()->move(QPoint(x, y)); }
Position PositionVector::transformToVectorCoordinates(const Position& p, bool extend) const { // XXX this duplicates most of the code in nearest_offset_to_point2D. It should be refactored if (extend) { PositionVector extended = *this; const SUMOReal dist = 2 * distance(p); extended.extrapolate(dist); return extended.transformToVectorCoordinates(p) - Position(dist, 0); } SUMOReal minDist = std::numeric_limits<SUMOReal>::max(); SUMOReal nearestPos = -1; SUMOReal seen = 0; int sign = 1; for (const_iterator i = begin(); i != end() - 1; i++) { const SUMOReal pos = GeomHelper::nearest_offset_on_line_to_point2D(*i, *(i + 1), p, true); const SUMOReal dist = pos < 0 ? minDist : p.distanceTo2D(Line(*i, *(i + 1)).getPositionAtDistance(pos)); if (dist < minDist) { nearestPos = pos + seen; minDist = dist; sign = isLeft(*i, *(i + 1), p) >= 0 ? -1 : 1; } if (i != begin() && pos == GeomHelper::INVALID_OFFSET) { // even if perpendicular is set we still need to check the distance to the inner points const SUMOReal cornerDist = p.distanceTo2D(*i); if (cornerDist < minDist) { const SUMOReal pos1 = GeomHelper::nearest_offset_on_line_to_point2D(*(i - 1), *i, p, false); const SUMOReal pos2 = GeomHelper::nearest_offset_on_line_to_point2D(*i, *(i + 1), p, false); if (pos1 == (*(i - 1)).distanceTo2D(*i) && pos2 == 0.) { nearestPos = seen; minDist = cornerDist; sign = isLeft(*(i - 1), *i, p) >= 0 ? -1 : 1; } } } seen += (*i).distanceTo2D(*(i + 1)); } if (nearestPos != -1) { return Position(nearestPos, sign * minDist); } else { return Position::INVALID; } }
int AnnotationToMask::wn_PnPoly(const Point& P, const std::vector<Point>& V) const { int wn = 0; // the winding number counter // loop through all edges of the polygon for (int i = 0; i<V.size() - 1; i++) { // edge from V[i] to V[i+1] if (V[i].getY() <= P.getY()) { // start y <= P.y if (V[i + 1].getY() > P.getY()) // an upward crossing if (isLeft(V[i], V[i + 1], P) > 0) // P left of edge ++wn; // have a valid up intersect } else { // start y > P.y (no test needed) if (V[i + 1].getY() <= P.getY()) // a downward crossing if (isLeft(V[i], V[i + 1], P) < 0) // P right of edge --wn; // have a valid down intersect } } return wn; }