//---------------------------------------------------------------------- TileCoords ArenaMap::getRandomLocationInArea( const TileCoords& pos, int radius ) const { TileCoords minXY( pos.x - radius, pos.y - radius ); TileCoords maxXY( pos.x + radius, pos.y + radius ); minXY.x = Monky::MathFuncs<int>::clamp( minXY.x, 0, m_arenaInfo.width - 1 ); minXY.y = Monky::MathFuncs<int>::clamp( minXY.y, 0, m_arenaInfo.height - 1 ); maxXY.x = Monky::MathFuncs<int>::clamp( maxXY.x, 0, m_arenaInfo.width - 1 ); maxXY.y = Monky::MathFuncs<int>::clamp( maxXY.y, 0, m_arenaInfo.height - 1 ); return TileCoords( Monky::RandNumGen::randInRangeInt( minXY.x, maxXY.x ), Monky::RandNumGen::randInRangeInt( minXY.y, maxXY.y ) ); }
void GPSView::AddGPSPoints(GPSPoints &p){ int width; int height; GetClientSize(&width, &height); Point minXY(-1, -1); Point maxXY(-1, -1); for (size_t i = 0; i < p.Count(); i++){ Point point = ProjectPoint(p[i]); minXY.x = ((minXY.x == -1) ? point.x : std::min(minXY.x, point.x)); minXY.y = ((minXY.y == -1) ? point.y : std::min(minXY.y, point.y)); m_trackPoints.Add(point); } for (size_t i = 0; i < m_trackPoints.size(); i++){ Point point = m_trackPoints[i]; point.x = point.x - minXY.x; point.y = point.y - minXY.y; // now, we need to keep track the max X and Y values maxXY.x = (maxXY.x == -1) ? point.x : std::max(maxXY.x, point.x); maxXY.y = (maxXY.y == -1) ? point.y : std::max(maxXY.y, point.y); } int paddingBothSides = MIN_PADDING * 2; // the actual drawing space for the map on the image int mapWidth = width - paddingBothSides; int mapHeight = height - paddingBothSides; // determine the width and height ratio because we need to magnify the map to fit into the given image dimension double mapWidthRatio = mapWidth / maxXY.x; double mapHeightRatio = mapHeight / maxXY.y; // using different ratios for width and height will cause the map to be stretched. So, we have to determine // the global ratio that will perfectly fit into the given image dimension m_globalRatio = std::min(mapWidthRatio, mapHeightRatio); // now we need to readjust the padding to ensure the map is always drawn on the center of the given image dimension m_heightPadding = (height - (m_globalRatio * maxXY.y)) / 2; m_widthPadding = (width - (m_globalRatio * maxXY.x)) / 2; m_offsetPoint = minXY; UpdateMinMax(m_trackPoints); RefreshBackground(); }
ccQuadric* ccQuadric::Fit(CCLib::GenericIndexedCloudPersist *cloud, double* rms/*=0*/) { //number of points unsigned count = cloud->size(); if (count < CC_LOCAL_MODEL_MIN_SIZE[HF]) { ccLog::Warning(QString("[ccQuadric::fitTo] Not enough points in input cloud to fit a quadric! (%1 at the very least are required)").arg(CC_LOCAL_MODEL_MIN_SIZE[HF])); return 0; } //project the points on a 2D plane CCVector3 G, X, Y, N; { CCLib::Neighbourhood Yk(cloud); //plane equation const PointCoordinateType* theLSQPlane = Yk.getLSQPlane(); if (!theLSQPlane) { ccLog::Warning("[ccQuadric::Fit] Not enough points to fit a quadric!"); return 0; } assert(Yk.getGravityCenter()); G = *Yk.getGravityCenter(); //local base N = CCVector3(theLSQPlane); assert(Yk.getLSQPlaneX() && Yk.getLSQPlaneY()); X = *Yk.getLSQPlaneX(); //main direction Y = *Yk.getLSQPlaneY(); //secondary direction } //project the points in a temporary cloud ccPointCloud tempCloud("temporary"); if (!tempCloud.reserve(count)) { ccLog::Warning("[ccQuadric::Fit] Not enough memory!"); return 0; } cloud->placeIteratorAtBegining(); for (unsigned k=0; k<count; ++k) { //projection into local 2D plane ref. CCVector3 P = *(cloud->getNextPoint()) - G; tempCloud.addPoint(CCVector3(P.dot(X),P.dot(Y),P.dot(N))); } CCLib::Neighbourhood Zk(&tempCloud); { //set exact values for gravity center and plane equation //(just to be sure and to avoid re-computing them) Zk.setGravityCenter(CCVector3(0,0,0)); PointCoordinateType perfectEq[4] = { 0, 0, 1, 0 }; Zk.setLSQPlane( perfectEq, CCVector3(1,0,0), CCVector3(0,1,0), CCVector3(0,0,1)); } uchar hfdims[3]; const PointCoordinateType* eq = Zk.getHeightFunction(hfdims); if (!eq) { ccLog::Warning("[ccQuadric::Fit] Failed to fit a quadric!"); return 0; } //we recenter the quadric object ccGLMatrix glMat(X,Y,N,G); ccBBox bb = tempCloud.getBB(); CCVector2 minXY(bb.minCorner().x,bb.minCorner().y); CCVector2 maxXY(bb.maxCorner().x,bb.maxCorner().y); ccQuadric* quadric = new ccQuadric(minXY, maxXY, eq, hfdims, &glMat); quadric->setMetaData(QString("Equation"),QVariant(quadric->getEquationString())); //compute rms if necessary if (rms) { const uchar& dX = hfdims[0]; const uchar& dY = hfdims[1]; const uchar& dZ = hfdims[2]; *rms = 0; for (unsigned k=0; k<count; ++k) { //projection into local 2D plane ref. const CCVector3* P = tempCloud.getPoint(k); PointCoordinateType z = eq[0] + eq[1]*P->u[dX] + eq[2]*P->u[dY] + eq[3]*P->u[dX]*P->u[dX] + eq[4]*P->u[dX]*P->u[dY] + eq[5]*P->u[dY]*P->u[dY]; *rms += (z-P->z)*(z-P->z); } if (count) { *rms = sqrt(*rms / count); quadric->setMetaData(QString("RMS"),QVariant(*rms)); } } return quadric; }
ccPlane* ccPlane::Fit(CCLib::GenericIndexedCloudPersist *cloud, double* rms/*=0*/) { //number of points unsigned count = cloud->size(); if (count < 3) { ccLog::Warning("[ccPlane::Fit] Not enough points in input cloud to fit a plane!"); return 0; } CCLib::Neighbourhood Yk(cloud); //plane equation const PointCoordinateType* theLSPlane = Yk.getLSPlane(); if (!theLSPlane) { ccLog::Warning("[ccPlane::Fit] Not enough points to fit a plane!"); return 0; } //get the centroid const CCVector3* G = Yk.getGravityCenter(); assert(G); //and a local base CCVector3 N(theLSPlane); const CCVector3* X = Yk.getLSPlaneX(); //main direction assert(X); CCVector3 Y = N * (*X); //compute bounding box in 2D plane CCVector2 minXY(0,0), maxXY(0,0); cloud->placeIteratorAtBegining(); for (unsigned k=0; k<count; ++k) { //projection into local 2D plane ref. CCVector3 P = *(cloud->getNextPoint()) - *G; CCVector2 P2D( P.dot(*X), P.dot(Y) ); if (k != 0) { if (minXY.x > P2D.x) minXY.x = P2D.x; else if (maxXY.x < P2D.x) maxXY.x = P2D.x; if (minXY.y > P2D.y) minXY.y = P2D.y; else if (maxXY.y < P2D.y) maxXY.y = P2D.y; } else { minXY = maxXY = P2D; } } //we recenter the plane PointCoordinateType dX = maxXY.x-minXY.x; PointCoordinateType dY = maxXY.y-minXY.y; CCVector3 Gt = *G + *X * (minXY.x + dX / 2) + Y * (minXY.y + dY / 2); ccGLMatrix glMat(*X,Y,N,Gt); ccPlane* plane = new ccPlane(dX, dY, &glMat); //compute least-square fitting RMS if requested if (rms) { *rms = CCLib::DistanceComputationTools::computeCloud2PlaneDistanceRMS(cloud, theLSPlane); plane->setMetaData(QString("RMS"),QVariant(*rms)); } return plane; }