void Rectangle::print() const { std::cout << "Rectangle: x: " << getX() << std::endl << " y: " << getY() << std::endl << " area: " << getArea() << std::endl << " perimeter: " << getPerimeter() << std::endl; }
//-------------------------------------------------- float ofPolyline::getIndexAtLength(float length) const { if(points.size() < 2) return 0; updateCache(); float totalLength = getPerimeter(); length = ofClamp(length, 0, totalLength); int lastPointIndex = isClosed() ? points.size() : points.size()-1; int i1 = ofClamp(floor(length / totalLength * lastPointIndex), 0, lengths.size()-2); // start approximation here int leftLimit = 0; int rightLimit = lastPointIndex; float distAt1, distAt2; for(int iterations = 0; iterations < 32; iterations ++) { // limit iterations i1 = ofClamp(i1, 0, lengths.size()-1); distAt1 = lengths[i1]; if(distAt1 <= length) { // if Length at i1 is less than desired Length (this is good) distAt2 = lengths[i1+1]; if(distAt2 >= length) { float t = ofMap(length, distAt1, distAt2, 0, 1); return i1 + t; } else { leftLimit = i1; } } else { rightLimit = i1; } i1 = (leftLimit + rightLimit)/2; } return 0; }
list<pos_t> scanner::scanlistLineOfSight(pos_t center, const pixelshade_map &scanmap, unsigned int radius) { set<pos_t> cups; forward_list<pos_t> perimeter = getPerimeter(center,radius); for(auto p:perimeter) getCupsInSight(scanmap,cups,p,center); return move( list<pos_t>( cups.begin(), cups.end() ) ); }
//---------------------------------------------------------- ofPolyline ofPolyline::getResampledByCount(int count) const { float perimeter = getPerimeter(); if(count < 2) { ofLogWarning("ofPolyline") << "getResampledByCount(): requested " << count <<" points, using minimum count of 2 "; count = 2; } return ofPolyline::getResampledBySpacing(perimeter / (count-1)); }
void Triangle::print() { gout<<setPos(0,400)<<"--------------------------------------------------------------------------------------------------------------"<<endg; gout<<setPos(200,405)<<"Shape info Follows for: Triangle"<<endg; gout<<setPos(200,420)<<"Point a: ("<<a.getX()<<","<<a.getY()<<")"<<endg; gout<<setPos(200,435)<<"Point b: ("<<b.getX()<<","<<b.getY()<<")"<<endg; gout<<setPos(200,450)<<"Point c: ("<<c.getX()<<","<<c.getY()<<")"<<endg; gout<<setPos(200,465)<<"Perimeter: "<<getPerimeter()<<" "<<"Area: "<<getArea()<<endg; }
ostream& Zone::operator<<(ostream &out) const { SerializationFactory& sf=SerializationFactory::getInstance(); core::SharedPointer<Serializer> s = sf.getSerializer(out); s->write(CRC32 < OPENDAVINCI_CORE_STRINGLITERAL2('i', 'd') >::RESULT, getID()); s->write(CRC32 < OPENDAVINCI_CORE_STRINGLITERAL4('n', 'a', 'm', 'e') >::RESULT, getName()); s->write(CRC32 < OPENDAVINCI_CORE_STRINGLITERAL8('p', 'e', 'r', 'i', 'm', 't', 'e', 'r') >::RESULT, getPerimeter()); uint32_t numberOfConnectors = static_cast<uint32_t>(m_listOfConnectors.size()); s->write(CRC32 < OPENDAVINCI_CORE_STRINGLITERAL8('n', 'u', 'm', 'c', 'o', 'n', 'n', 's') >::RESULT, numberOfConnectors); // Write connectors to stringstream. stringstream sstr; for (uint32_t i = 0; i < numberOfConnectors; i++) { // Write data to stringstream. sstr << m_listOfConnectors.at(i); } // Write connectors. if (numberOfConnectors > 0) { s->write(CRC32 < OPENDAVINCI_CORE_STRINGLITERAL5('c', 'o', 'n', 'n', 's') >::RESULT, sstr.str()); } uint32_t numberOfSpots = static_cast<uint32_t>(m_listOfSpots.size()); s->write(CRC32 < OPENDAVINCI_CORE_STRINGLITERAL8('n', 'u', 'm', 's', 'p', 'o', 't', 's') >::RESULT, numberOfSpots); // Write spots to stringstream. sstr.str(""); for (uint32_t i = 0; i < numberOfSpots; i++) { // Write data to stringstream. sstr << m_listOfSpots.at(i); } // Write spots. if (numberOfSpots > 0) { s->write(CRC32 < OPENDAVINCI_CORE_STRINGLITERAL5('s', 'p', 'o', 't', 's') >::RESULT, sstr.str()); } return out; }
//---------------------------------------------------------- ofPolyline ofPolyline::getResampledBySpacing(float spacing) const { if(spacing==0 || size() == 0) return *this; ofPolyline poly; float totalLength = getPerimeter(); for(float f=0; f<totalLength; f += spacing) { poly.lineTo(getPointAtLength(f)); } if(!isClosed()) { if(poly.size() > 0) poly.points.back() = points.back(); poly.setClosed(false); } else { poly.setClosed(true); } return poly; }
string Shapes::toString() const { std::ostringstream sout; sout << "Shape Information" << "\n-----------------\n"; sout << "Type of this:\t" << typeid(this).name() << "\n"; sout << "Type of *this:\t" << typeid(*this).name() << "\n"; sout << "Generic name:\t" << getGenericName() << "\n"; sout << "Description:\t" << getDesripName() << "\n"; sout << "id:\t\t" << myUniqueID << "\n"; // force derived classes to call members sout << "H extent:\t"<< getHorizontalExtend()<< "\n"; sout << "V extent:\t"<< getVerticalExtend()<< "\n"; sout << "Scr area:\t"<< getScreenArea()<< "\n"; sout << "Geo area:\t"<< getArea()<< "\n"; sout << "Scr perimeter:\t"<< getScreenPerimeter()<< "\n"; sout << "Geo perimeter:\t"<< getPerimeter()<< "\n"; return sout.str(); }
// Print the contents of this Rectangle. // Override the method to customize it for Square. // If no ostream parameter is supplied, default will be cout. void Square::print( ostream & output ) { cout << "--------------------------------\n"; output << TYPE << "\n"; cout << "--------------------------------\n"; output << "Points:\n"; output << "\tA = " << A << "\n"; output << "\tB = " << B << "\n"; output << "\tC = " << C << "\n"; output << "\tD = " << D << "\n"; output << "Side Lengths:\n"; output << "\tAB = " << A.getDistance( B ) << "\n"; output << "\tBC = " << B.getDistance( C ) << "\n"; output << "\tCD = " << C.getDistance( D ) << "\n"; output << "\tDA = " << D.getDistance( A ) << "\n"; output << "Shape Properties:\n"; output << "\tlength = " << length << "\n"; output << "\tPerimeter = " << getPerimeter() << "\n"; output << "\tArea = " << getArea() << "\n\n"; }
// Print the contents of this Quadrilateral. // Override the method to customize it for Trapezoid. // If no ostream parameter is supplied, default will be cout. void Trapezoid::print( ostream & output ) { output << "------------------------\n"; output << TYPE << "\n"; output << "------------------------\n"; output << "Points:\n"; output << "\tA = " << A << "\n"; output << "\tB = " << B << "\n"; output << "\tC = " << C << "\n"; output << "\tD = " << D << "\n"; output << "Side Lengths:\n"; output << "\tAB = " << A.getDistance( B ) << "\n"; output << "\tBC = " << B.getDistance( C ) << "\n"; output << "\tCD = " << C.getDistance( D ) << "\n"; output << "\tDA = " << D.getDistance( A ) << "\n"; output << "Shape Properties:\n"; output << "\tbase1= " << base1 << "\n"; output << "\tbase2 = " << base2 << "\n"; output << "\theight = " << height << "\n"; output << "\tPerimeter = " << getPerimeter() << "\n"; output << "\tArea = " << getArea() << "\n\n"; }
//------------------------------------------------------------ ofxPolyline ofxPolyline::getResampledAndVerticesBySpacing(float spacing) { // Get resampled points while keeping vertices ofxPolyline polyline; polyline.setStrokeLinecap(getStrokeLinecap()); polyline.setStrokeLinejoin(getStrokeLinejoin()); float totalLength = getPerimeter(); int currentIndex = 1; ofVec2f prevPoint = ofVec2f(FLT_MAX, FLT_MAX); for(float f=0; f<totalLength; f += spacing) { float index = getIndexAtLength(f); while (index > currentIndex) { ofVec2f newPoint = (*this)[currentIndex]; // Don't add if this point is very close to the prev point if (!newPoint.match(prevPoint)) { polyline.lineTo(newPoint); prevPoint = newPoint; } currentIndex++; } ofVec2f newPoint = getPointAtLength(f); // Don't add if this point is very close to the prev point if (!newPoint.match(prevPoint)) { polyline.lineTo(newPoint); prevPoint = newPoint; } } if(!isClosed()) { if(polyline.size() > 0) { polyline[polyline.size()-1] = (*this)[size()-1]; } polyline.setClosed(false); } else { polyline.setClosed(true); } return polyline; }
//---------------------------------------------------------- ofPolyline ofPolyline::getResampledByCount(int count) { float perimeter = getPerimeter(); return ofPolyline::getResampledBySpacing(perimeter / count); }
// Getters private double Circle::getSegmentWidth() { return getPerimeter() / segments; }
void MarkerDetector::recognizeMarkers(const cv::Mat& grayscale, std::vector<Marker>& detectedMarkers) { std::vector<Marker> goodMarkers; // Identify the markers for (size_t i=0;i<detectedMarkers.size();i++) { Marker& marker = detectedMarkers[i]; // Find the perspective transformation that brings current marker to rectangular form //cv::Mat markerTransform = cv::getPerspectiveTransform(marker.points, m_markerCorners2d); cv::Mat markerTransform = cv::findHomography(marker.points, m_markerCorners2d); // Transform image to get a canonical marker image cv::warpPerspective(grayscale, canonicalMarkerImage, markerTransform, cv::Size(markerLength,markerLength)); int nRotations; int id = Marker::getMarkerId(canonicalMarkerImage, nRotations); if (id !=- 1) { marker.id = id; //sort the points so that they are always in the same order no matter the camera orientation std::rotate(marker.points.begin(), marker.points.begin() + 4 - nRotations, marker.points.end()); goodMarkers.push_back(marker); } } // Refine marker corners using sub pixel accuracy if (goodMarkers.size() > 0) { std::vector<cv::Point2f> preciseCorners(4 * goodMarkers.size()); for (size_t i=0; i<goodMarkers.size(); i++) { const Marker& marker = goodMarkers[i]; for (int c = 0; c <4; c++) { preciseCorners[i*4 + c] = marker.points[c]; } } //cv::TermCriteria termCriteria = cv::TermCriteria(cv::TermCriteria::MAX_ITER | cv::TermCriteria::EPS, 30, 0.01); //cv::TermCriteria termCriteria = cv::TermCriteria(cv::TermCriteria::MAX_ITER | cv::TermCriteria::EPS, 3, 0.05); cv::TermCriteria termCriteria = cv::TermCriteria(cv::TermCriteria::MAX_ITER | cv::TermCriteria::EPS, 30, 0.01); cv::cornerSubPix(grayscale, preciseCorners, cvSize(5,5), cvSize(-1,-1), termCriteria); // Copy refined corners position back to markers for (size_t i=0; i<goodMarkers.size(); i++) { Marker& marker = goodMarkers[i]; for (int c=0;c<4;c++) { marker.points[c] = preciseCorners[i*4 + c]; } } } //sort by id std::sort ( goodMarkers.begin(),goodMarkers.end() ); //there might be still the case that a marker is detected twice because of the double border indicated earlier, //detect and remove these cases std::vector<bool> toRemove ( goodMarkers.size(),false ); for ( int i=0;i<int ( goodMarkers.size() )-1;i++ ) { if ( goodMarkers[i].id==goodMarkers[i+1].id && !toRemove[i+1] ) { //std::cout<<"remove: "<<goodMarkers[i].id<<std::endl; //deletes the one with smaller perimeter if ( getPerimeter ( goodMarkers[i].points ) >getPerimeter ( goodMarkers[i+1].points ) ) toRemove[i+1]=true; else toRemove[i]=true; } } detectedMarkers.clear(); for (size_t i=0;i<goodMarkers.size();i++) { if (!toRemove[i]) detectedMarkers.push_back(goodMarkers[i]); } }
void MarkerDetector::findCandidates(cv::Mat src, std::vector<Marker>& detectedMarkers, int minPoints, int maxPoints) { cv::Mat thres2; src.copyTo ( thres2 ); std::vector<cv::Vec4i> hierarchy2; ContoursVector allContours; std::vector<cv::Point> approxCurve; std::vector<Marker> possibleMarkers; cv::findContours(thres2, allContours,hierarchy2, CV_RETR_LIST, CV_CHAIN_APPROX_NONE); for (size_t i=0; i<allContours.size(); i++) { int contourSize = allContours[i].size(); if ( minPoints< contourSize && contourSize<maxPoints ) { //drawContours( src, allContours, i, cv::Scalar(0,0,255), CV_FILLED, 8); cv::approxPolyDP(allContours[i], approxCurve, double(contourSize * 0.05), true); // Selecting only those with 4 points (corners) if (approxCurve.size() != 4) continue; // Selecting only convex polygons if (!cv::isContourConvex(cv::Mat(approxCurve))) continue; // Ensure that the distance between consecutive points is large enough float minDist = std::numeric_limits<float>::max(); for (int i = 0; i < 4; i++) { cv::Point side = approxCurve[i] - approxCurve[(i+1)%4]; //float squaredSideLength = side.dot(side); float squaredSideLength= std::sqrt ( ( float ) ( approxCurve[i].x-approxCurve[ ( i+1 ) %4].x ) * ( approxCurve[i].x-approxCurve[ ( i+1 ) %4].x ) + ( approxCurve[i].y-approxCurve[ ( i+1 ) %4].y ) * ( approxCurve[i].y-approxCurve[ ( i+1 ) %4].y ) ); //std::cout<<squaredSideLength<< " " <<test<<std::endl; //minDist = std::min(minDist, squaredSideLength); if ( squaredSideLength<minDist ) minDist=squaredSideLength; } // Selecting those whose minimum side length is still greater than the limit if (minDist <= 10) continue; // All tests are passed. Save marker candidate: Marker m; for (int i = 0; i<4; i++) m.points.push_back( cv::Point2f(approxCurve[i].x,approxCurve[i].y) ); // Sort the points in anti-clockwise order // Trace a line between the first and second point. // If the third point is at the right side, then the points are anti-clockwise cv::Point v1 = m.points[1] - m.points[0]; cv::Point v2 = m.points[2] - m.points[0]; double o = (v1.x * v2.y) - (v1.y * v2.x); if (o < 0.0) //if the third point is in the left side, then sort in anti-clockwise order std::swap(m.points[1], m.points[3]); possibleMarkers.push_back(m); } } // Remove these elements which corners are too close to each other. // First detect candidates for removal: std::vector< std::pair<int,int> > tooNearCandidates; for (size_t i=0;i<possibleMarkers.size();i++) { const Marker& m1 = possibleMarkers[i]; //calculate the average distance of each corner to the nearest corner of the other marker candidate for (size_t j=i+1;j<possibleMarkers.size();j++) { const Marker& m2 = possibleMarkers[j]; float distSquared = 0; for (int c = 0; c < 4; c++) { /* distSquared+= sqrt ( ( m1.points[c].x-m2.points[c].x ) * ( m1.points[c].x-m2.points[c].x ) + ( m1.points[c].y-m2.points[c].y ) * ( m1.points[c].y-m2.points[c].y ) ); */ distSquared+= sqrt ( ( possibleMarkers[i].points[c].x-possibleMarkers[j].points[c].x ) * ( possibleMarkers[i].points[c].x-possibleMarkers[j].points[c].x ) + ( possibleMarkers[i].points[c].y-possibleMarkers[j].points[c].y ) * ( possibleMarkers[i].points[c].y-possibleMarkers[j].points[c].y ) ); //cv::Point v = m1.points[c] - m2.points[c]; //distSquared2 += v.dot(v); } distSquared /= 4; if (distSquared < 10) { tooNearCandidates.push_back(std::pair<int,int>(i,j)); } } } // Mark for removal the element of the pair with smaller perimeter std::vector<bool> removalMask (possibleMarkers.size(), false); for (size_t i=0; i<tooNearCandidates.size(); i++) { float p1 = getPerimeter(possibleMarkers[tooNearCandidates[i].first ].points); float p2 = getPerimeter(possibleMarkers[tooNearCandidates[i].second].points); size_t removalIndex; if (p1 > p2) removalIndex = tooNearCandidates[i].second; else removalIndex = tooNearCandidates[i].first; removalMask[removalIndex] = true; } // Return candidates detectedMarkers.clear(); for (size_t i=0;i<possibleMarkers.size();i++) { if (!removalMask[i]) detectedMarkers.push_back(possibleMarkers[i]); } }
void Castle::generateWall() { addRectangles(); getPerimeter(); }
void Castle::regenerateWall() { cleanMatrix(); addRectangles(); getPerimeter(); }
//-------------------------------------------------- ofPoint ofPolyline::getPointAtPercent(float f) const { float length = getPerimeter(); return getPointAtLength(f * length); }
//-------------------------------------------------- float ofPolyline::getIndexAtPercent(float f) const { return getIndexAtLength(f * getPerimeter()); }
double getArea() { double halfPerimeter = getPerimeter() / 2; return sqrt((halfPerimeter - side1) * (halfPerimeter - side2) * (halfPerimeter - side3) * halfPerimeter); }