vector<PointD> generateSegment(PointD startPoint, PointD endPoint, double step, const char* filename) { vector<PointD> P; //AB: y = a x + b where a = dy/dx and b = yA - a(xA) double dx = endPoint[0] - startPoint[0] , dy = endPoint[1] - startPoint[1]; double x, y; if(dx == 0) //vertical line { x = startPoint[0]; if(startPoint[1]<endPoint[1]) for(y = startPoint[1]; y <= endPoint[1]; y += step) P.push_back(PointD(x,y)); else for(y = startPoint[1]; y >= endPoint[1]; y -= step) P.push_back(PointD(x,y)); } else { double a = dy/dx; double b = startPoint[1] - a*startPoint[0]; if(startPoint[0]<endPoint[0]) for(x = startPoint[0]; x <= endPoint[0]; x += step) P.push_back(PointD(x,a*x+b)); else for(x = startPoint[0]; x >= endPoint[0]; x -= step) P.push_back(PointD(x,a*x+b)); } /* save into files */ std::ofstream FILE(filename); for(vector<PointD>::const_iterator it = P.begin(); it != P.end(); it++) { FILE << (*it)[0]<<" "<<(*it)[1] <<'\n'; } /* save into files */ return P; }
void FixSubgraphSizes(ICluster * cluster, RectD & parentRect) { RectD childRect; for(IClusterSet::const_iterator itr = cluster->GetClusters().begin(); itr != cluster->GetClusters().end(); ++itr) { std::string cluster; FixSubgraphSizes(itr->get(), childRect); } for(IVertexSet::const_iterator itr = cluster->GetVertices().begin(); itr != cluster->GetVertices().end(); ++itr) { if (childRect.IsEmptyArea()) childRect = GetBoundingRect(itr->get()); else childRect.Union(GetBoundingRect(itr->get())); } //if (!GetBoundingRect(cluster).Contains(childRect)) { if (childRect.IsEmptyArea()) childRect = GetBoundingRect(cluster); else childRect.Union(GetBoundingRect(cluster)); if (ElementG * eg = GetElementG(cluster)) { assert(eg->m_polygons.size() == 1); if (eg->m_polygons.size() == 1) { eg->m_polygons[0]->m_points.clear(); eg->m_polygons[0]->SetBoundingBox(RectD()); eg->m_polygons[0]->m_points.push_back(PointD(childRect.GetLeft(), childRect.GetBottom())); eg->m_polygons[0]->m_points.push_back(PointD(childRect.GetLeft(), childRect.GetTop())); eg->m_polygons[0]->m_points.push_back(PointD(childRect.GetRight(), childRect.GetTop())); eg->m_polygons[0]->m_points.push_back(PointD(childRect.GetRight(), childRect.GetBottom())); eg->m_polygons[0]->m_points.push_back(PointD(childRect.GetLeft(), childRect.GetBottom())); } //eg->SetBoundingBox(childRect); eg->CalcBoundingBox(); } //childRect.Union(GetBoundingRect(cluster)); //ElementGPtr elementG = new ElementG(childRect); //cluster->SetProperty(SVG_PROP_ELEMENTG, elementG); } if (parentRect.IsEmptyArea()) parentRect = childRect; else parentRect.Union(childRect); }
PolygonD Node::get_polygon() const { log("calling get_polygon from a node at position (%f,%f)",cast_to_double(point.x()),cast_to_double(point.y())); Arrangement_2::Face_const_handle f; Arrangement_2::Halfedge_const_handle h; Arrangement_2::Vertex_const_handle v; PolygonD poly; if (CGAL::assign(f,spl.locate(Point_2(point.x(),point.y())))) { Arrangement_2::Ccb_halfedge_const_circulator c=f->outer_ccb(); Arrangement_2::Ccb_halfedge_const_circulator start=c; do { poly.push_back(PointD(cast_to_double(c->source()->point().x()),cast_to_double(c->source()->point().y()))); c++; } while (c!=start); } else if (CGAL::assign(h,spl.locate(Point_2(point.x(),point.y())))) { log("error: expected face, not halfedge!"); } else if (CGAL::assign(v,spl.locate(Point_2(point.x(),point.y())))) { log("error: expected face, not vertex!"); } else { log("error: expected face, didn't find anything!"); } return poly; }
vector<PointD> generateArc(PointD center, double radius, double angleStart, double angleEnd, const char* filename) { vector<PointD> P; double step = 1/radius; if(angleStart<angleEnd) for(double theta = angleStart; theta<angleEnd; theta += step) P.push_back(PointD(center[0]+radius*sin(theta), center[1]+radius*cos(theta))); else for(double theta = angleEnd; theta<angleStart; theta += step) P.push_back(PointD(center[0]+radius*sin(theta), center[1]+radius*cos(theta))); /* save into files */ std::ofstream FILE(filename); for(vector<PointD>::const_iterator it = P.begin(); it != P.end(); it++) { FILE << (*it)[0]<<" "<<(*it)[1] <<'\n'; } /* save into files */ return P; }
bool TextSelection::IsOverGlyph(int pageNo, double x, double y) { int textLen; RectI* coords; textCache->GetData(pageNo, &textLen, &coords); int glyphIx = FindClosestGlyph(pageNo, x, y); PointI pt = PointD(x, y).ToInt(); // when over the right half of a glyph, FindClosestGlyph returns the // index of the next glyph, in which case glyphIx must be decremented if (glyphIx == textLen || !coords[glyphIx].Contains(pt)) glyphIx--; if (-1 == glyphIx) return false; return coords[glyphIx].Contains(pt); }
// returns the index of the glyph closest to the right of the given coordinates // (i.e. when over the right half of a glyph, the returned index will be for the // glyph following it, which will be the first glyph (not) to be selected) int TextSelection::FindClosestGlyph(int pageNo, double x, double y) { int textLen; RectI* coords; textCache->GetData(pageNo, &textLen, &coords); PointD pt = PointD(x, y); unsigned int maxDist = UINT_MAX; PointI pti = pt.ToInt(); bool overGlyph = false; int result = -1; for (int i = 0; i < textLen; i++) { if (!coords[i].x && !coords[i].dx) continue; if (overGlyph && !coords[i].Contains(pti)) continue; unsigned int dist = distSq((int)x - coords[i].x - coords[i].dx / 2, (int)y - coords[i].y - coords[i].dy / 2); if (dist < maxDist) { result = i; maxDist = dist; } // prefer glyphs the cursor is actually over if (!overGlyph && coords[i].Contains(pti)) { overGlyph = true; result = i; maxDist = dist; } } if (-1 == result) return 0; CrashIf(result < 0 || result >= textLen); // the result indexes the first glyph to be selected in a forward selection RectD bbox = engine->Transform(coords[result].Convert<double>(), pageNo, 1.0, 0); pt = engine->Transform(pt, pageNo, 1.0, 0); if (pt.x > bbox.x + 0.5 * bbox.dx) { result++; // for some (DjVu) documents, all glyphs of a word share the same bbox while (result < textLen && coords[result - 1] == coords[result]) result++; } CrashIf(result > 0 && result < textLen && coords[result] == coords[result - 1]); return result; }
PointD determineCenter(PointD p1, PointD p2, PointD p3) { double a1, b1, a2, b2, c1, c2; double xA, yA, xB, yB, xC, yC; xA=p1[0]; yA=p1[1]; xB=p2[0]; yB=p2[1]; xC=p3[0]; yC=p3[1]; a1=xA-xB; b1=yA-yB; a2=xA-xC; b2=yA-yC; c1=(xA*xA-xB*xB+yA*yA-yB*yB)/2; c2=(xA*xA-xC*xC+yA*yA-yC*yC)/2; double x,y,dentaY; dentaY=b1*a2-a1*b2; if(dentaY!=0) { y= (double)(c1*a2-a1*c2)/(double)dentaY; if (a1!=0) x=(double)(c1-b1*y)/(double)a1; else if(a2!=0) x=(double)(c2-b2*y)/(double)a2; else { cout<<"Error: 3 points of the arc are colinear."<<endl; x=-1; y=-1; } } else { x=-1; y=-1; } return PointD(x,y); }
vector<PointD> generateCircle(PointD center, double radius, const char* filename) { vector<PointD> P; /* * x = sin(theta)*r * y = cos(theta)*r */ double step = 1/radius; for(double theta = 0; theta<2*M_PI; theta += step) P.push_back(PointD(center[0]+radius*sin(theta), center[1]+radius*cos(theta))); /* save into files */ /* std::ofstream FILE(filename); std::ostream_iterator<PointD> output_iterator(FILE, "\n"); std::copy(P.begin(), P.end(), output_iterator); */ std::ofstream FILE(filename); for(vector<PointD>::const_iterator it = P.begin(); it != P.end(); it++) { FILE << (*it)[0]<<" "<<(*it)[1] <<'\n'; } /* save into files */ return P; }
static void GeomTest() { PointD ptD(12.4, -13.6); utassert(ptD.x == 12.4 && ptD.y == -13.6); PointI ptI = ptD.ToInt(); utassert(ptI.x == 12 && ptI.y == -14); ptD = ptI.Convert<double>(); utassert(PointD(12, -14) == ptD); utassert(PointD(12.4, -13.6) != ptD); SizeD szD(7.7, -3.3); utassert(szD.dx == 7.7 && szD.dy == -3.3); SizeI szI = szD.ToInt(); utassert(szI.dx == 8 && szI.dy == -3); szD = szI.Convert<double>(); utassert(SizeD(8, -3) == szD); utassert(!szD.IsEmpty() && !szI.IsEmpty()); utassert(SizeI().IsEmpty() && SizeD().IsEmpty()); struct SRIData { int x1s, x1e, y1s, y1e; int x2s, x2e, y2s, y2e; bool intersect; int i_xs, i_xe, i_ys, i_ye; int u_xs, u_xe, u_ys, u_ye; } testData[] = { { 0,10, 0,10, 0,10, 0,10, true, 0,10, 0,10, 0,10, 0,10 }, /* complete intersect */ { 0,10, 0,10, 20,30,20,30, false, 0, 0, 0, 0, 0,30, 0,30 }, /* no intersect */ { 0,10, 0,10, 5,15, 0,10, true, 5,10, 0,10, 0,15, 0,10 }, /* { | } | */ { 0,10, 0,10, 5, 7, 0,10, true, 5, 7, 0,10, 0,10, 0,10 }, /* { | | } */ { 0,10, 0,10, 5, 7, 5, 7, true, 5, 7, 5, 7, 0,10, 0,10 }, { 0,10, 0,10, 5, 15,5,15, true, 5,10, 5,10, 0,15, 0,15 }, }; for (size_t i = 0; i < dimof(testData); i++) { struct SRIData *curr = &testData[i]; RectI rx1(curr->x1s, curr->y1s, curr->x1e - curr->x1s, curr->y1e - curr->y1s); RectI rx2 = RectI::FromXY(curr->x2s, curr->y2s, curr->x2e, curr->y2e); RectI isect = rx1.Intersect(rx2); if (curr->intersect) { utassert(!isect.IsEmpty()); utassert(isect.x == curr->i_xs && isect.y == curr->i_ys); utassert(isect.x + isect.dx == curr->i_xe && isect.y + isect.dy == curr->i_ye); } else { utassert(isect.IsEmpty()); } RectI urect = rx1.Union(rx2); utassert(urect.x == curr->u_xs && urect.y == curr->u_ys); utassert(urect.x + urect.dx == curr->u_xe && urect.y + urect.dy == curr->u_ye); /* if we swap rectangles, the results should be the same */ std::swap(rx1, rx2); isect = rx1.Intersect(rx2); if (curr->intersect) { utassert(!isect.IsEmpty()); utassert(isect.x == curr->i_xs && isect.y == curr->i_ys); utassert(isect.x + isect.dx == curr->i_xe && isect.y + isect.dy == curr->i_ye); } else { utassert(isect.IsEmpty()); } urect = rx1.Union(rx2); utassert(RectI::FromXY(curr->u_xs, curr->u_ys, curr->u_xe, curr->u_ye) == urect); utassert(!rx1.Contains(PointI(-2, -2))); utassert(rx1.Contains(rx1.TL())); utassert(!rx1.Contains(PointI(rx1.x, INT_MAX))); utassert(!rx1.Contains(PointI(INT_MIN, rx1.y))); } }
virtual void OnStartElement(const XML_Char *pszName, const XML_Char **papszAttrs) { CStackParser::OnStartElement(pszName, papszAttrs); CElementPtr e = m_stack.top(); if (0 == e->m_tag.compare("svg")) { m_valid = true; for(hpcc::IClusterSet::const_iterator itr = m_graph->GetAllClusters().begin(); itr != m_graph->GetAllClusters().end(); ++itr) { itr->get()->SetProperty(SVG_PROP_ELEMENTG, (CUnknown *)NULL); } for(hpcc::IVertexSet::const_iterator itr = m_graph->GetAllVertices().begin(); itr != m_graph->GetAllVertices().end(); ++itr) { itr->get()->SetProperty(SVG_PROP_ELEMENTG, (CUnknown *)NULL); } for(hpcc::IEdgeSet::const_iterator itr = m_graph->GetAllEdges().begin(); itr != m_graph->GetAllEdges().end(); ++itr) { itr->get()->SetProperty(SVG_PROP_ELEMENTG, (CUnknown *)NULL); } } else if (m_valid && 0 == e->m_tag.compare("g")) { if (m_offset.Empty()) { std::string transform = e->m_attr["transform"]; if (!transform.empty()) { static const char * const TRANSLATE = "translate("; static int TRANSLATE_SIZE = strlen(TRANSLATE); const char * start = strstr(transform.c_str(), TRANSLATE); const char * mid = strstr(start, " "); const char * end = strstr(mid, ")"); if (start && mid && end) { char x[8], y[8]; memset(x, 0, 8); memset(y, 0, 8); strncpy(x, start + TRANSLATE_SIZE, mid - (start + TRANSLATE_SIZE)); strncpy(y, mid + 1, end - (mid + 1)); m_offset = CreatePointD(x, y, PointD(), DOT_DPI); } } } GRAPH_TYPE type = GRAPH_TYPE_UNKNOWN; if (e->m_attr["class"].compare("graph") == 0) type = GRAPH_TYPE_GRAPH; else if (e->m_attr["class"].compare("cluster") == 0) type = GRAPH_TYPE_CLUSTER; else if (e->m_attr["class"].compare("node") == 0) type = GRAPH_TYPE_VERTEX; else if (e->m_attr["class"].compare("edge") == 0) type = GRAPH_TYPE_EDGE; m_currentItem = m_graph->GetGraphItem(type, e->m_attr["id"]); if (!m_currentItem) { throw ParseException(); } m_currentElementG = new ElementG(); m_currentItem->SetProperty(SVG_PROP_ELEMENTG, m_currentElementG); } return; }
void ScatterWidget::addData(float x, float y, string legend) { addData(PointD(x, y), legend); }
bool OsmAnd::MapObjectsSymbolsProvider_P::computeSymbolPinPoint( const QVector<float>& pathSegmentsLengthInPixels, const float pathLengthInPixels, const QVector<double>& pathSegmentsLength31, const QVector<PointI>& path31, const ComputedPinPoint& blockPinPoint, const float neededZoomPixelScaleFactor, const float offsetFromBlockPinPointInPixelsOnNeededZoom, ComputedPinPoint& outComputedSymbolPinPoint) const { const auto pathSegmentsCount = pathSegmentsLengthInPixels.size(); const auto offsetFromOriginPathPoint = (pathSegmentsLengthInPixels[blockPinPoint.basePathPointIndex] * blockPinPoint.normalizedOffsetFromBasePathPoint * neededZoomPixelScaleFactor) + offsetFromBlockPinPointInPixelsOnNeededZoom; if (offsetFromOriginPathPoint >= 0.0f) { // In case start point is located after origin point ('on the right'), usual search is used auto testPathPointIndex = blockPinPoint.basePathPointIndex; auto scannedLength = 0.0f; while (scannedLength <= offsetFromOriginPathPoint) { if (testPathPointIndex >= pathSegmentsCount) return false; const auto segmentLength = pathSegmentsLengthInPixels[testPathPointIndex] * neededZoomPixelScaleFactor; if (scannedLength + segmentLength >= offsetFromOriginPathPoint) { const auto pathPointIndex = testPathPointIndex; const auto offsetFromPathPoint = offsetFromOriginPathPoint - scannedLength; const auto nOffsetFromPoint = offsetFromPathPoint / segmentLength; const auto& segmentStartPoint31 = path31[testPathPointIndex + 0]; const auto& segmentEndPoint31 = path31[testPathPointIndex + 1]; const auto& vSegment31 = segmentEndPoint31 - segmentStartPoint31; outComputedSymbolPinPoint.point31 = segmentStartPoint31 + PointI(PointD(vSegment31) * nOffsetFromPoint); outComputedSymbolPinPoint.basePathPointIndex = pathPointIndex; outComputedSymbolPinPoint.offsetFromBasePathPoint31 = pathSegmentsLength31[testPathPointIndex] * nOffsetFromPoint; outComputedSymbolPinPoint.normalizedOffsetFromBasePathPoint = nOffsetFromPoint; return true; } scannedLength += segmentLength; testPathPointIndex++; } } else { // In case start point is located before origin point ('on the left'), reversed search is used if (blockPinPoint.basePathPointIndex == 0) return false; auto testPathPointIndex = blockPinPoint.basePathPointIndex - 1; auto scannedLength = 0.0f; while (scannedLength >= offsetFromOriginPathPoint) { const auto& segmentLength = pathSegmentsLengthInPixels[testPathPointIndex] * neededZoomPixelScaleFactor; if (scannedLength - segmentLength <= offsetFromOriginPathPoint) { const auto pathPointIndex = testPathPointIndex; const auto offsetFromPathPoint = segmentLength + (offsetFromOriginPathPoint - scannedLength); const auto nOffsetFromPoint = offsetFromPathPoint / segmentLength; const auto& segmentStartPoint31 = path31[testPathPointIndex + 0]; const auto& segmentEndPoint31 = path31[testPathPointIndex + 1]; const auto& vSegment31 = segmentEndPoint31 - segmentStartPoint31; outComputedSymbolPinPoint.point31 = segmentStartPoint31 + PointI(PointD(vSegment31) * nOffsetFromPoint); outComputedSymbolPinPoint.basePathPointIndex = pathPointIndex; outComputedSymbolPinPoint.offsetFromBasePathPoint31 = pathSegmentsLength31[testPathPointIndex] * nOffsetFromPoint; outComputedSymbolPinPoint.normalizedOffsetFromBasePathPoint = nOffsetFromPoint; return true; } scannedLength -= segmentLength; if (testPathPointIndex == 0) return false; testPathPointIndex--; } } return false; }
bool OsmAnd::MapObjectsSymbolsProvider_P::computeBlockPinPoint( const QVector<float>& pathSegmentsLengthInPixels, const float pathLengthInPixels, const QVector<double>& pathSegmentsLength31, const QVector<PointI>& path31, const float blockWidthInPixels, const float offsetFromPathStartInPixels, const unsigned int scanOriginPathPointIndex, const float scanOriginPathPointOffsetInPixels, unsigned int& outNextScanOriginPathPointIndex, float& outNextScanOriginPathPointOffsetInPixels, ComputedPinPoint& outComputedBlockPinPoint) const { const auto pathSegmentsCount = pathSegmentsLengthInPixels.size(); const auto startOffset = offsetFromPathStartInPixels; const auto pinPointOffset = startOffset + blockWidthInPixels / 2.0f; const auto endOffset = startOffset + blockWidthInPixels; if (endOffset > pathLengthInPixels) return false; bool blockPinPointFound = false; auto testPathPointIndex = scanOriginPathPointIndex; auto scannedLengthInPixels = scanOriginPathPointOffsetInPixels; while (scannedLengthInPixels <= pinPointOffset) { if (testPathPointIndex >= pathSegmentsCount) { assert(false); return false; } const auto& segmentLengthInPixels = pathSegmentsLengthInPixels[testPathPointIndex]; if (scannedLengthInPixels + segmentLengthInPixels >= pinPointOffset) { const auto nOffsetFromPoint = (pinPointOffset - scannedLengthInPixels) / segmentLengthInPixels; const auto& segmentStartPoint31 = path31[testPathPointIndex + 0]; const auto& segmentEndPoint31 = path31[testPathPointIndex + 1]; const auto& vSegment31 = segmentEndPoint31 - segmentStartPoint31; // Compute block pin-point outComputedBlockPinPoint.point31 = segmentStartPoint31 + PointI(PointD(vSegment31) * nOffsetFromPoint); outComputedBlockPinPoint.basePathPointIndex = testPathPointIndex; outComputedBlockPinPoint.offsetFromBasePathPoint31 = pathSegmentsLength31[testPathPointIndex] * nOffsetFromPoint; outComputedBlockPinPoint.normalizedOffsetFromBasePathPoint = nOffsetFromPoint; blockPinPointFound = true; outNextScanOriginPathPointIndex = testPathPointIndex; outNextScanOriginPathPointOffsetInPixels = scannedLengthInPixels; break; } scannedLengthInPixels += segmentLengthInPixels; testPathPointIndex++; } while (scannedLengthInPixels < endOffset) { if (testPathPointIndex >= pathSegmentsCount) { assert(false); return false; } const auto& segmentLengthInPixels = pathSegmentsLengthInPixels[testPathPointIndex]; if (scannedLengthInPixels + segmentLengthInPixels > endOffset) { outNextScanOriginPathPointIndex = testPathPointIndex; outNextScanOriginPathPointOffsetInPixels = scannedLengthInPixels; break; } scannedLengthInPixels += segmentLengthInPixels; testPathPointIndex++; } return blockPinPointFound; }
PointD Map::getTurnOuterCorner(int x, int y, const TilePathNode& turn) const { static const double displacement = m_game->getTrackTileMargin() + std::min(m_game->getCarWidth(), m_game->getCarHeight()) / 2; static const double bigDisplacement = m_game->getTrackTileSize() - displacement; static const std::map<model::TileType, PointD> displacementMap = { { model::LEFT_TOP_CORNER, PointD(displacement, displacement) }, { model::LEFT_BOTTOM_CORNER, PointD(displacement, bigDisplacement) }, { model::RIGHT_TOP_CORNER, PointD(bigDisplacement, displacement) }, { model::RIGHT_BOTTOM_CORNER, PointD(bigDisplacement, bigDisplacement) }, // others not yet implemented }; model::TileType tileType = getTileType(x, y); switch (tileType) { case model::LEFT_HEADED_T: case model::RIGHT_HEADED_T: case model::TOP_HEADED_T: case model::BOTTOM_HEADED_T: case model::CROSSROADS: { // T-turn or crossroads handling is similar to corresponding usual turn struct TurnTuple { TilePathNode::AbsoluteTurn from, to; bool operator==(const TurnTuple&r) const { return from == r.from && to == r.to; } }; typedef std::pair<TurnTuple, model::TileType> TurnsCornerPair; static const TurnsCornerPair turnsToCorner[] = { { { AbsoluteDirection::UP, AbsoluteDirection::RIGHT }, model::LEFT_TOP_CORNER }, { { AbsoluteDirection::LEFT, AbsoluteDirection::DOWN }, model::LEFT_TOP_CORNER }, { { AbsoluteDirection::UP, AbsoluteDirection::LEFT}, model::RIGHT_TOP_CORNER }, { { AbsoluteDirection::RIGHT, AbsoluteDirection::DOWN }, model::RIGHT_TOP_CORNER }, { { AbsoluteDirection::LEFT, AbsoluteDirection::UP }, model::LEFT_BOTTOM_CORNER }, { { AbsoluteDirection::DOWN, AbsoluteDirection::RIGHT }, model::LEFT_BOTTOM_CORNER }, { { AbsoluteDirection::RIGHT, AbsoluteDirection::UP}, model::RIGHT_BOTTOM_CORNER }, { { AbsoluteDirection::DOWN, AbsoluteDirection::LEFT}, model::RIGHT_BOTTOM_CORNER }, }; TurnTuple thisTurn = {turn.m_turnAbsoluteFrom, turn.m_turnAbsolute/*to*/}; auto found = std::find_if(std::begin(turnsToCorner), std::end(turnsToCorner), [&thisTurn](const TurnsCornerPair& tupleCornerPair) { return tupleCornerPair.first == thisTurn; }); if (found != std::end(turnsToCorner)) { tileType = found->second; // assume this crossroad to be usual turn } break; } default: break; } auto displacementIt = displacementMap.find(tileType); return getTileCorner(x, y) + (displacementIt != displacementMap.end() ? displacementIt->second : m_tileCenter); }