void GLHelper::drawShapeDottedContour(const int type, const PositionVector& frontShape, const double offsetFrontShape, const PositionVector& backShape, const double offsetBackShape) { glPushMatrix(); // build contour using shapes of first and last lane shapes PositionVector contourFront = frontShape; PositionVector contourback = backShape; contourFront.move2side(offsetFrontShape); contourback.move2side(offsetBackShape); contourback = contourback.reverse(); for (auto i : contourback) { contourFront.push_back(i); } contourFront.push_back(frontShape.front()); // resample shape PositionVector resampledShape = contourFront.resample(1); // draw contour over shape glTranslated(0, 0, type + 2); // set custom line width glLineWidth(3); // draw contour GLHelper::drawLine(resampledShape, getDottedcontourColors((int)resampledShape.size())); //restore line width glLineWidth(1); glPopMatrix(); }
bool TraCIServer::findObjectShape(int domain, const std::string& id, PositionVector& shape) { Position p; switch (domain) { case CMD_SUBSCRIBE_INDUCTIONLOOP_CONTEXT: if (TraCIServerAPI_InductionLoop::getPosition(id, p)) { shape.push_back(p); return true; } break; case CMD_SUBSCRIBE_MULTI_ENTRY_EXIT_DETECTOR_CONTEXT: break; case CMD_SUBSCRIBE_TL_CONTEXT: break; case CMD_SUBSCRIBE_LANE_CONTEXT: if (TraCIServerAPI_Lane::getShape(id, shape)) { return true; } break; case CMD_SUBSCRIBE_VEHICLE_CONTEXT: if (TraCIServerAPI_Vehicle::getPosition(id, p)) { shape.push_back(p); return true; } break; case CMD_SUBSCRIBE_VEHICLETYPE_CONTEXT: break; case CMD_SUBSCRIBE_ROUTE_CONTEXT: break; case CMD_SUBSCRIBE_POI_CONTEXT: if (TraCIServerAPI_POI::getPosition(id, p)) { shape.push_back(p); return true; } return false; case CMD_SUBSCRIBE_POLYGON_CONTEXT: if (TraCIServerAPI_Polygon::getShape(id, shape)) { return true; } break; case CMD_SUBSCRIBE_JUNCTION_CONTEXT: if (TraCIServerAPI_Junction::getPosition(id, p)) { shape.push_back(p); return true; } break; case CMD_SUBSCRIBE_EDGE_CONTEXT: if (TraCIServerAPI_Edge::getShape(id, shape)) { return true; } break; case CMD_SUBSCRIBE_SIM_CONTEXT: return false; case CMD_SUBSCRIBE_GUI_CONTEXT: break; default: break; } return false; }
void GLHelper::drawShapeDottedContour(const int type, const Position& center, const double width, const double height, const double rotation, const double offsetX, const double offsetY) { glPushMatrix(); // create shape around center PositionVector shape; shape.push_back(Position(width / 2, height / 2)); shape.push_back(Position(width / -2, height / 2)); shape.push_back(Position(width / -2, height / -2)); shape.push_back(Position(width / 2, height / -2)); shape.push_back(Position(width / 2, height / 2)); // resample shape shape = shape.resample(1); // draw contour over shape glTranslated(center.x(), center.y(), type + 2); // set custom line width glLineWidth(3); // rotate glRotated(rotation, 0, 0, 1); // translate offset glTranslated(offsetX, offsetY, 0); // draw contour GLHelper::drawLine(shape, getDottedcontourColors((int)shape.size())); //restore line width glLineWidth(1); glPopMatrix(); }
PositionVector GeomHelper::makeRing(const double radius1, const double radius2, const Position& center, unsigned int nPoints) { if (nPoints < 3) { WRITE_ERROR("GeomHelper::makeRing() requires nPoints>=3"); } if (radius1 >= radius2) { WRITE_ERROR("GeomHelper::makeRing() requires radius2>radius1"); } PositionVector ring; ring.push_back({radius1, 0}); ring.push_back({radius2, 0}); for (unsigned int i = 1; i < nPoints; ++i) { const double a = 2.0 * M_PI * (double)i / (double) nPoints; ring.push_back({radius2 * cos(a), radius2 * sin(a)}); } ring.push_back({radius2, 0}); ring.push_back({radius1, 0}); for (unsigned int i = 1; i < nPoints; ++i) { const double a = -2.0 * M_PI * (double)i / (double) nPoints; ring.push_back({radius1 * cos(a), radius1 * sin(a)}); } ring.push_back({radius1, 0}); ring.add(center); return ring; }
void GLHelper::drawShapeDottedContour(const int type, const PositionVector& shape, const double width) { glPushMatrix(); // build contour using shapes of first and last lane shapes PositionVector contourFront = shape; // only add an contourback if width is greather of 0 if (width > 0) { PositionVector contourback = contourFront; contourFront.move2side(width); contourback.move2side(-width); contourback = contourback.reverse(); for (auto i : contourback) { contourFront.push_back(i); } contourFront.push_back(shape.front()); } // resample shape PositionVector resampledShape = contourFront.resample(1); // draw contour over shape glTranslated(0, 0, type + 2); // set custom line width glLineWidth(3); // draw contour drawLine(resampledShape, getDottedcontourColors((int)resampledShape.size())); //restore line width glLineWidth(1); glPopMatrix(); }
/* Test the method 'area'*/ TEST_F(PositionVectorTest, test_method_area) { PositionVector square; square.push_back(Position(0,0)); square.push_back(Position(1,0)); square.push_back(Position(1,1)); square.push_back(Position(0,1)); // open EXPECT_DOUBLE_EQ(square.area(), 1); square.push_back(Position(0,0)); // closed EXPECT_DOUBLE_EQ(square.area(), 1); }
/* Test the method 'getCentroid'.*/ TEST_F(PositionVectorTest, test_method_getCentroid) { PositionVector square; square.push_back(Position(0,0)); square.push_back(Position(1,0)); square.push_back(Position(1,1)); square.push_back(Position(0,1)); EXPECT_EQ(Position(0.5, 0.5), square.getCentroid()); Position pos2 = vectorLine->getCentroid(); EXPECT_DOUBLE_EQ(1, pos2.x()); EXPECT_DOUBLE_EQ(1, pos2.y()); }
virtual void SetUp() { vectorPolygon = new PositionVector(); vectorPolygon->push_back(Position(0,0)); vectorPolygon->push_back(Position(0,2)); vectorPolygon->push_back(Position(2,4)); vectorPolygon->push_back(Position(4,2)); vectorPolygon->push_back(Position(4,0)); vectorLine = new PositionVector(); vectorLine->push_back(Position(0,0)); vectorLine->push_back(Position(2,2)); }
double NBHeightMapper::getZ(const Position& geo) const { if (!ready()) { WRITE_WARNING("Cannot supply height since no height data was loaded"); return 0; } if (myRaster != 0) { double result = -1e6; if (myBoundary.around(geo)) { const int xSize = int((myBoundary.xmax() - myBoundary.xmin()) / mySizeOfPixel.x() + .5); const double normX = (geo.x() - myBoundary.xmin()) / mySizeOfPixel.x(); const double normY = (geo.y() - myBoundary.ymax()) / mySizeOfPixel.y(); PositionVector corners; corners.push_back(Position(floor(normX) + 0.5, floor(normY) + 0.5, myRaster[(int)normY * xSize + (int)normX])); if (normX - floor(normX) > 0.5) { corners.push_back(Position(floor(normX) + 1.5, floor(normY) + 0.5, myRaster[(int)normY * xSize + (int)normX + 1])); } else { corners.push_back(Position(floor(normX) - 0.5, floor(normY) + 0.5, myRaster[(int)normY * xSize + (int)normX - 1])); } if (normY - floor(normY) > 0.5) { corners.push_back(Position(floor(normX) + 0.5, floor(normY) + 1.5, myRaster[((int)normY + 1) * xSize + (int)normX])); } else { corners.push_back(Position(floor(normX) + 0.5, floor(normY) - 0.5, myRaster[((int)normY - 1) * xSize + (int)normX])); } result = Triangle(corners).getZ(Position(normX, normY)); } if (result > -1e5 && result < 1e5) { return result; } } // coordinates in degrees hence a small search window float minB[2]; float maxB[2]; minB[0] = (float)geo.x() - 0.00001f; minB[1] = (float)geo.y() - 0.00001f; maxB[0] = (float)geo.x() + 0.00001f; maxB[1] = (float)geo.y() + 0.00001f; QueryResult queryResult; int hits = myRTree.Search(minB, maxB, queryResult); Triangles result = queryResult.triangles; assert(hits == (int)result.size()); UNUSED_PARAMETER(hits); // only used for assertion for (Triangles::iterator it = result.begin(); it != result.end(); it++) { const Triangle* triangle = *it; if (triangle->contains(geo)) { return triangle->getZ(geo); } } WRITE_WARNING("Could not get height data for coordinate " + toString(geo)); return 0; }
PositionVector GeomHelper::makeCircle(const double radius, const Position& center, unsigned int nPoints) { if (nPoints < 3) { WRITE_ERROR("GeomHelper::makeCircle() requires nPoints>=3"); } PositionVector circle; circle.push_back({radius, 0}); for (unsigned int i = 1; i < nPoints; ++i) { const double a = 2.0 * M_PI * (double)i / (double) nPoints; circle.push_back({radius * cos(a), radius * sin(a)}); } circle.push_back({radius, 0}); circle.add(center); return circle; }
bool NIVissimSingleTypeParser_Geschwindigkeitsverteilungsdefinition::parse(std::istream& from) { // id std::string id; from >> id; // list of points PositionVector points; std::string tag; do { tag = readEndSecure(from); if (tag == "name") { readName(from); tag = readEndSecure(from); } if (tag != "DATAEND") { SUMOReal p1 = TplConvert::_2SUMOReal(tag.c_str()); from >> tag; SUMOReal p2 = TplConvert::_2SUMOReal(tag.c_str()); points.push_back(Position(p1, p2)); } } while (tag != "DATAEND"); NBDistribution::dictionary("speed", id, new Distribution_Points(id, points)); return true; }
void NIVissimDistrictConnection::dict_BuildDistrictNodes(NBDistrictCont& dc, NBNodeCont& nc) { for (std::map<int, std::vector<int> >::iterator k = myDistrictsConnections.begin(); k != myDistrictsConnections.end(); k++) { // get the connections const std::vector<int>& connections = (*k).second; // retrieve the current district std::string dsid = toString<int>((*k).first); NBDistrict* district = new NBDistrict(dsid); dc.insert(district); // compute the middle of the district PositionVector pos; for (std::vector<int>::const_iterator j = connections.begin(); j != connections.end(); j++) { NIVissimDistrictConnection* c = dictionary(*j); pos.push_back(c->geomPosition()); } Position distCenter = pos.getPolygonCenter(); if (connections.size() == 1) { // !!! ok, ok, maybe not the best way just to add an offset distCenter.add(10, 10); } district->setCenter(distCenter); // build the node std::string id = "District" + district->getID(); NBNode* districtNode = new NBNode(id, district->getPosition(), district); if (!nc.insert(districtNode)) { throw 1; } } }
void PosCluster::add2Vector (PositionVector& out) const { CIterator it (iterator ()); for (; it.hasNext () ; it.next ()) { out.push_back (*it); } }
void PCLoaderXML::myCharacters(int element, const std::string& chars) { if (element == SUMO_TAG_POLY) { bool ok = true; PositionVector pshape = GeomConvHelper::parseShapeReporting(chars, "poly", myCurrentID.c_str(), ok, false); if (!ok) { return; } const PositionVector::ContType& cont = pshape.getCont(); PositionVector shape; for (PositionVector::ContType::const_iterator i = cont.begin(); i != cont.end(); ++i) { Position pos((*i)); if (!GeoConvHelper::getProcessing().x2cartesian(pos)) { WRITE_WARNING("Unable to project coordinates for polygon '" + myCurrentID + "'."); } shape.push_back(pos); } Polygon* poly = new Polygon(myCurrentID, myCurrentType, myCurrentColor, shape, false); if (!myCont.insert(myCurrentID, poly, myCurrentLayer, myCurrentIgnorePrunning)) { WRITE_ERROR("Polygon '" + myCurrentID + "' could not been added."); delete poly; } } }
void NIImporter_VISUM::parse_AreaSubPartElement() { SUMOLong id = TplConvert::_2long(myLineParser.get("TFLAECHEID").c_str()); SUMOLong edgeid = TplConvert::_2long(myLineParser.get("KANTEID").c_str()); if (myEdges.find(edgeid) == myEdges.end()) { WRITE_ERROR("Unknown edge in TEILFLAECHENELEMENT"); return; } std::string dir = myLineParser.get("RICHTUNG"); // get index (unused) // std::string indexS = NBHelpers::normalIDRepresentation(myLineParser.get("INDEX")); // int index = -1; // try { // index = TplConvert::_2int(indexS.c_str()) - 1; // } catch (NumberFormatException&) { // WRITE_ERROR("An index for a TEILFLAECHENELEMENT is not numeric (id='" + toString(id) + "')."); // return; // } PositionVector shape; shape.push_back(myPoints[myEdges[edgeid].first]); shape.push_back(myPoints[myEdges[edgeid].second]); if (dir.length() > 0 && dir[0] == '1') { shape = shape.reverse(); } if (mySubPartsAreas.find(id) == mySubPartsAreas.end()) { WRITE_ERROR("Unkown are for area part '" + myCurrentID + "'."); return; } const std::vector<SUMOLong>& areas = mySubPartsAreas.find(id)->second; for (std::vector<SUMOLong>::const_iterator i = areas.begin(); i != areas.end(); ++i) { NBDistrict* d = myShapeDistrictMap[*i]; if (d == 0) { continue; } if (myDistrictShapes.find(d) == myDistrictShapes.end()) { myDistrictShapes[d] = PositionVector(); } if (dir.length() > 0 && dir[0] == '1') { myDistrictShapes[d].push_back(myPoints[myEdges[edgeid].second]); myDistrictShapes[d].push_back(myPoints[myEdges[edgeid].first]); } else { myDistrictShapes[d].push_back(myPoints[myEdges[edgeid].first]); myDistrictShapes[d].push_back(myPoints[myEdges[edgeid].second]); } } }
PositionVector PositionVector::reverse() const { PositionVector ret; for (const_reverse_iterator i = rbegin(); i != rend(); i++) { ret.push_back(*i); } return ret; }
bool TraCIServerAPI_Polygon::getShape(const std::string& id, PositionVector& shape) { Polygon* poly = getPolygon(id); if (poly == 0) { return false; } shape.push_back(poly->getShape()); return true; }
bool NIImporter_DlrNavteq::NodesHandler::report(const std::string& result) { if (result[0] == '#') { return true; } std::string id; double x, y; int no_geoms, intermediate; // parse std::istringstream stream(result); // id stream >> id; if (stream.fail()) { throw ProcessError("Something is wrong with the following data line\n" + result); } // intermediate? stream >> intermediate; if (stream.fail()) { if (myNodeCont.size() == 0) { // be generous with extra data at beginning of file return true; } throw ProcessError("Non-numerical value for intermediate status in node " + id + "."); } // number of geometrical information stream >> no_geoms; if (stream.fail()) { throw ProcessError("Non-numerical value for number of geometries in node " + id + "."); } // geometrical information PositionVector geoms; for (int i = 0; i < no_geoms; i++) { stream >> x; if (stream.fail()) { throw ProcessError("Non-numerical value for x-position in node " + id + "."); } stream >> y; if (stream.fail()) { throw ProcessError("Non-numerical value for y-position in node " + id + "."); } Position pos(x, y); if (!NBNetBuilder::transformCoordinate(pos, true)) { throw ProcessError("Unable to project coordinates for node " + id + "."); } geoms.push_back(pos); } if (intermediate == 0) { NBNode* n = new NBNode(id, geoms[0]); if (!myNodeCont.insert(n)) { delete n; throw ProcessError("Could not add node '" + id + "'."); } } else { myGeoms[id] = geoms; } return true; }
// Returns the PositionVector to the endCells Pathfinder::PositionVector* Pathfinder::getPath(Cell* pEndCell){ PositionVector* path = new PositionVector; Cell* cell = pEndCell; while (cell != nullptr){ path->push_back(cell->getPosition()); cell = cell->getParentCell(); } return path; }
bool TraCIServerAPI_Lane::getShape(const std::string& id, PositionVector& shape) { const MSLane* const l = MSLane::dictionary(id); if (l == 0) { return false; } shape.push_back(l->getShape()); return true; }
void NWWriter_OpenDrive::checkLaneGeometries(const NBEdge* e) { if (e->getNumLanes() > 1) { // compute 'stop line' of rightmost lane const PositionVector shape0 = e->getLaneShape(0); assert(shape0.size() >= 2); const Position& from = shape0[-2]; const Position& to = shape0[-1]; PositionVector stopLine; stopLine.push_back(to); stopLine.push_back(to - PositionVector::sideOffset(from, to, -1000.0)); // endpoints of all other lanes should be on the stop line for (int lane = 1; lane < e->getNumLanes(); ++lane) { const double dist = stopLine.distance2D(e->getLaneShape(lane)[-1]); if (dist > NUMERICAL_EPS) { WRITE_WARNING("Uneven stop line at lane '" + e->getLaneID(lane) + "' (dist=" + toString(dist) + ") cannot be represented in OpenDRIVE."); } } } }
// =========================================================================== // method definitions // =========================================================================== PositionVector GeomConvHelper::parseShapeReporting(const std::string& shpdef, const std::string& objecttype, const char* objectid, bool& ok, bool allowEmpty, bool report) { if (shpdef == "") { if (!allowEmpty) { emitError(report, "Shape", objecttype, objectid, "the shape is empty"); ok = false; } return PositionVector(); } StringTokenizer st(shpdef, " "); PositionVector shape; while (st.hasNext()) { StringTokenizer pos(st.next(), ","); if (pos.size() != 2 && pos.size() != 3) { emitError(report, "Shape", objecttype, objectid, "the position is neither x,y nor x,y,z"); ok = false; return PositionVector(); } try { SUMOReal x = TplConvert::_2SUMOReal(pos.next().c_str()); SUMOReal y = TplConvert::_2SUMOReal(pos.next().c_str()); if (pos.size() == 2) { shape.push_back(Position(x, y)); } else { SUMOReal z = TplConvert::_2SUMOReal(pos.next().c_str()); shape.push_back(Position(x, y, z)); } } catch (NumberFormatException&) { emitError(report, "Shape", objecttype, objectid, "not numeric position entry"); ok = false; return PositionVector(); } catch (EmptyData&) { emitError(report, "Shape", objecttype, objectid, "empty position entry"); ok = false; return PositionVector(); } } return shape; }
PositionVector NIImporter_SUMO::reconstructEdgeShape(const EdgeAttrs* edge, const Position& from, const Position& to) { const PositionVector& firstLane = edge->lanes[0]->shape; PositionVector result; result.push_back(from); // reverse logic of NBEdge::computeLaneShape // !!! this will only work for old-style constant width lanes const size_t noLanes = edge->lanes.size(); for (unsigned int i = 1; i < firstLane.size() - 1; i++) { Position from = firstLane[i - 1]; Position me = firstLane[i]; Position to = firstLane[i + 1]; std::pair<SUMOReal, SUMOReal> offsets = NBEdge::laneOffset( from, me, SUMO_const_laneWidthAndOffset, (unsigned int)noLanes - 1, noLanes, edge->lsf, false); std::pair<SUMOReal, SUMOReal> offsets2 = NBEdge::laneOffset( me, to, SUMO_const_laneWidthAndOffset, (unsigned int)noLanes - 1, noLanes, edge->lsf, false); Line l1( Position(from.x() + offsets.first, from.y() + offsets.second), Position(me.x() + offsets.first, me.y() + offsets.second)); l1.extrapolateBy(100); Line l2( Position(me.x() + offsets2.first, me.y() + offsets2.second), Position(to.x() + offsets2.first, to.y() + offsets2.second)); l2.extrapolateBy(100); if (l1.intersects(l2)) { result.push_back(l1.intersectsAt(l2)); } else { WRITE_WARNING("Could not reconstruct shape for edge '" + edge->id + "'."); } } result.push_back(to); return result; }
PositionVector PositionVector::getSubpartByIndex(int beginIndex, int count) const { if (beginIndex < 0) { beginIndex += (int)size(); } assert(count > 0); assert(beginIndex < (int)size()); assert(beginIndex + count <= (int)size()); PositionVector result; for (int i = beginIndex; i < beginIndex + count; ++i) { result.push_back((*this)[i]); } return result; }
PositionVector NIImporter_SUMO::reconstructEdgeShape(const EdgeAttrs* edge, const Position& from, const Position& to) { const PositionVector& firstLane = edge->lanes[0]->shape; PositionVector result; result.push_back(from); // reverse logic of NBEdge::computeLaneShape // !!! this will only work for old-style constant width lanes const size_t noLanes = edge->lanes.size(); SUMOReal offset; if (edge->lsf == LANESPREAD_RIGHT) { offset = (SUMO_const_laneWidth + SUMO_const_laneOffset) / 2.; // @todo: why is the lane offset counted in here? } else { offset = (SUMO_const_laneWidth) / 2. - (SUMO_const_laneWidth * (SUMOReal)noLanes - 1) / 2.; ///= -2.; // @todo: actually, when looking at the road networks, the center line is not in the center } for (unsigned int i = 1; i < firstLane.size() - 1; i++) { const Position& from = firstLane[i - 1]; const Position& me = firstLane[i]; const Position& to = firstLane[i + 1]; Position offsets = PositionVector::sideOffset(from, me, offset); Position offsets2 = PositionVector::sideOffset(me, to, offset); PositionVector l1(from - offsets, me - offsets); l1.extrapolate(100); PositionVector l2(me - offsets2, to - offsets2); l2.extrapolate(100); if (l1.intersects(l2)) { result.push_back(l1.intersectionPosition2D(l2)); } else { WRITE_WARNING("Could not reconstruct shape for edge '" + edge->id + "'."); } } result.push_back(to); return result; }
bool TraCIServer::readTypeCheckingPolygon(tcpip::Storage& inputStorage, PositionVector& into) { if (inputStorage.readUnsignedByte() != TYPE_POLYGON) { return false; } into.clear(); unsigned int noEntries = inputStorage.readUnsignedByte(); PositionVector shape; for (unsigned int i = 0; i < noEntries; ++i) { SUMOReal x = inputStorage.readDouble(); SUMOReal y = inputStorage.readDouble(); into.push_back(Position(x, y)); } return true; }
SUMOReal PositionVector::area() const { if (size() < 3) { return 0; } SUMOReal area = 0; PositionVector tmp = *this; if (!isClosed()) { // make sure its closed tmp.push_back(tmp[0]); } const int endIndex = (int)tmp.size() - 1; // http://en.wikipedia.org/wiki/Polygon for (int i = 0; i < endIndex; i++) { area += tmp[i].x() * tmp[i + 1].y() - tmp[i + 1].x() * tmp[i].y(); } if (area < 0) { // we whether we had cw or ccw order area *= -1; } return area / 2; }
void GNENet::replaceJunctionByGeometry(GNEJunction* junction, GNEUndoList* undoList) { undoList->p_begin("Replace junction by geometry"); assert(junction->getNBNode()->checkIsRemovable()); std::vector<std::pair<NBEdge*, NBEdge*> > toJoin = junction->getNBNode()->getEdgesToJoin(); for (std::vector<std::pair<NBEdge*, NBEdge*> >::iterator j = toJoin.begin(); j != toJoin.end(); j++) { GNEEdge* begin = myEdges[(*j).first->getID()]; GNEEdge* continuation = myEdges[(*j).second->getID()]; deleteEdge(begin, undoList); deleteEdge(continuation, undoList); GNEEdge* newEdge = createEdge(begin->getSource(), continuation->getDest(), begin, undoList, begin->getMicrosimID(), false, true); PositionVector newShape = begin->getNBEdge()->getInnerGeometry(); newShape.push_back(junction->getNBNode()->getPosition()); newShape.append(continuation->getNBEdge()->getInnerGeometry()); newEdge->setAttribute(SUMO_ATTR_SHAPE, toString(newShape), undoList); // @todo what about trafficlights at the end of oontinuation? } deleteJunction(junction, undoList); undoList->p_end(); }
PositionVector PositionVector::getSubpart2D(SUMOReal beginOffset, SUMOReal endOffset) const { PositionVector ret; Position begPos = front(); if (beginOffset > POSITION_EPS) { begPos = positionAtOffset2D(beginOffset); } Position endPos = back(); if (endOffset < length() - POSITION_EPS) { endPos = positionAtOffset2D(endOffset); } ret.push_back(begPos); SUMOReal seen = 0; const_iterator i = begin(); // skip previous segments while ((i + 1) != end() && seen + (*i).distanceTo2D(*(i + 1)) < beginOffset) { seen += (*i).distanceTo2D(*(i + 1)); i++; } // append segments in between while ((i + 1) != end() && seen + (*i).distanceTo2D(*(i + 1)) < endOffset) { ret.push_back_noDoublePos(*(i + 1)); /* if(ret.at(-1)!=*(i+1)) { ret.push_back(*(i+1)); } */ seen += (*i).distanceTo2D(*(i + 1)); i++; } // append end ret.push_back_noDoublePos(endPos); return ret; }
LexerRule::LexerRule(const std::string& regex) { typedef std::vector<size_t> PositionVector; bool escape = false; PositionVector wildcardPositions; // record wildcards for(auto character : regex) { if(character == '\\') { escape = true; continue; } if(escape) { _regex.push_back(character); escape = false; continue; } if(character == '*') { wildcardPositions.push_back(_regex.size()); } _regex.push_back(character); } for(auto position : wildcardPositions) { _wildcards.insert(_regex.begin() + position); } }