// covert the number to decimal double double Base2Decimal(const char* src, unsigned int src_base, unsigned int percision){ unsigned int numSize = strlen(src); double digitPower = 0; double newNum = 0; int startNum = 0; int i = 0; unsigned int fracPointIndex = findPoint(src); // case of negative number (src[0] == '-') ? startNum = 1 : startNum = 0; // case there is no fraction point if (fracPointIndex == numSize) return (double)atoi(src); // create left side of fraction point for (i = fracPointIndex - 1; i >= startNum; --i) newNum += (pow(src_base, digitPower++))*(char2num(src[i])); digitPower = -1; // create right side of fraction point for (i = (int)fracPointIndex + 1; i < (int)numSize; ++i) newNum += (pow(src_base, digitPower--))*(char2num(src[i])); // case of negative number if (src[0] == '-') newNum = -(newNum); return newNum; }
// calibration function to be run at the beginning only vector<double> calibrate(){ cvSmooth(frame, imageFiltree, CV_BLUR,seuilFiltre,seuilFiltre,0.0,0.0); cvCvtColor(imageFiltree, imageHSV,CV_BGR2HSV); cvInRangeS(imageHSV,cvScalar(hmin, smin, vmin, 0.0),cvScalar(hmax, smax, vmax, 0.0),imageBinaire); cvErode(imageBinaire, imageErodee, NULL, nbErosions); cvDilate(imageErodee, imageDilatee, NULL, nbDilatations); imageObjectRGB = multBinColor(imageDilatee, frame); imageObjectHSV = multBinColor(imageDilatee, imageHSV); vector<vector<CvPoint3D32f> > vecDistinctPoints = findPoint(); // find the centroid of the object and trace it vector<CvPoint> centroid = centroiding(vecDistinctPoints); sort(centroid); vector<double> tanAlphaT = vector<double>(centroid.size(),0); double p; for (int i=0; i<centroid.size(); i++){ p = abs(centroid[i].x - (frame->width / 2)); tanAlphaT[i] = atan(d/D-p*ratioPixelSizeF); } return tanAlphaT; }
bool TlevelsPage::TwidgetCurves::setCursor(void) { POINT cp; GetCursorPos(&cp); ScreenToClient(h,&cp); std::pair<int,int> pt=findPoint(cp.x,cp.y); return pt.first>40?(curpoint=-1,false):(curpoint=pt.second,true); }
void callback(int i) { float time; clock_t t1, t2; // Start timer t1 = clock(); // Filtering, HSV to Binary Image, Erosions and Dilations cvSmooth(frame, imageFiltree, CV_BLUR,seuilFiltre,seuilFiltre,0.0,0.0); cvCvtColor(imageFiltree, imageHSV,CV_BGR2HSV); cvInRangeS(imageHSV,cvScalar(hmin, smin, vmin, 0.0),cvScalar(hmax, smax, vmax, 0.0),imageBinaire); cvErode(imageBinaire, imageErodee, NULL, nbErosions); cvDilate(imageErodee, imageDilatee, NULL, nbDilatations); //imageDilateeFiltree = lowPassFilter(imageDilatee); FILTER // multiplication between the original image in RGB and HSV and the binary image imageObjectRGB = multBinColor(imageDilatee, frame); imageObjectHSV = multBinColor(imageDilatee, imageHSV); // find the points and separate them (rows correspond to each point and the columns to the pixels belonging to the points) vector<vector<CvPoint3D32f> > vecDistinctPoints = findPoint(); // find the centroid of the point and trace it vector<CvPoint> centroid = centroiding(vecDistinctPoints); // sort the centroids centroid = sort(centroid); // compute the distance with and without lens distortion vector<double> distance = findDistance(imageObjectHSV, centroid, tanAlphaT); // Contours /*cvFindContours( imageDilatee, storage, &contours, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_NONE, cvPoint(0,0) );*/ /*cvDrawContours( frame, contours, CV_RGB(255,255,0), CV_RGB(0,255,0), 1, 2, 8, cvPoint(0,0));*/ cvNamedWindow(myWindow, CV_WINDOW_AUTOSIZE); cvNamedWindow(myWindowObjectHSV, CV_WINDOW_AUTOSIZE); cvNamedWindow(myWindowObjectRGB, CV_WINDOW_AUTOSIZE); cvShowImage(myWindow, frame); cvShowImage(myWindowObjectHSV, imageObjectHSV); cvShowImage(myWindowObjectRGB, imageObjectRGB); //cvSaveImage("NoisyGridCentroiding.png", imageObjectRGB,0); // End timer t2 = clock(); // Compute execution time time = (float)(t2 - t1) / CLOCKS_PER_SEC; cout << "execution time = " << time << " s" << endl; }
void AngleVariation::initialise() { // Calculate points positions QPointF tempPoint = QPointF(); tempPoint.setX(branchLine.p2().x() - branchLine.p1().x()); tempPoint.setY(branchLine.p2().y() - branchLine.p1().y()); branchAngle = atan2(tempPoint.y(), tempPoint.x()); origPoint = findPoint(branchAngle - variationAngle); variationPoint = calculateOpposingPoint(origPoint); }
// remove trailing zeros void removeTrailingZeros(char** strNew){ char* str = *strNew; unsigned int fracPointIndex = findPoint(str); unsigned int index = strlen(str) - 1; char clearZero = 1; // while need to clear zeros or reached the fraction point while (clearZero == 1 && index > fracPointIndex){ // replace 0 with NULL if (str[index] == '0') str[index--] = '\0'; else clearZero = 0; } }
bool Line::find(DRAWDEBUG_PARAM_N){ LinePoint lp; LinePoint::LinePointParam lParam = m_LineParam; lParam.sobelThreshold = 50; bool found = findPoint(lp,lParam DRAWDEBUG_ARG); m_points.clear(); //std::cout<<"found::::: "<<found<<" "<<lParam.edge<<std::endl; if(!found){ return false; } m_points.push_front(lp); //found receptor point -> try to extend the line extend(true DRAWDEBUG_ARG); extend(false DRAWDEBUG_ARG); return true; }
void LaserSystem::addBeams(Laser& laser, TilePosition& tilePos) { // Setup everything currentPosition = ng::vec::cast<int>(tilePos.pos); currentDirection = laser.direction; // Current layer is the starting layer of the beam currentLayer = (tilePos.layer && !getLayer()); // Simulate the laser until it hits something laser.beamCount = 0; sf::Vector2f startPoint = tileMap.getCenterPoint<float>(tilePos.pos); PointInfo endPoint; do { // Find next point that collides endPoint = findPoint(); Laser::Beam* beam; if (laser.beamCount < laser.beams.size()) { // Use an existing sprite beam = &(laser.beams[laser.beamCount]); } else { // Setup a new sprite with the beam texture laser.beams.emplace_back(); beam = &laser.beams.back(); ng::SpriteLoader::load(beam->sprite, textureFilename, true); } ++laser.beamCount; beam->sprite.setOrigin(beamWidth / 2, 0); // Calculate and set the beam length float beamLength = ng::vec::distance(startPoint, endPoint.position); beam->sprite.setScale(1, beamLength); // Set the beam's position and rotation beam->sprite.setPosition(startPoint); beam->sprite.setRotation(ng::vec::rotateAngle(laser.getAngle(currentDirection), 180.0)); // Set the beam's layer beam->layer = currentLayer; if (endPoint.state == PointInfo::State::Redirect) { // Change the direction based on the angle of the mirror bool mirrorState = tileMapData(endPoint.tileId).state; changeDirection(mirrorState, currentDirection); } else if (endPoint.state == PointInfo::State::Activate) { // Enable the laser sensor es::Events::send(SwitchEvent{endPoint.tileId, SwitchEvent::On}); laserSensorsToDisable.erase(endPoint.tileId); } startPoint = endPoint.position; } while (endPoint.state == PointInfo::State::Redirect); }
int main(int argc, char **argv) { google::SetUsageMessage("dense --help"); google::SetVersionString("1.0.0"); google::ParseCommandLineFlags(&argc, &argv, true); int maxCorners = 10000; double qualityLevel = 0.03; double minDistance = 2; std::vector<cv::Mat> all_images; std::vector<cv::Mat> all_gray_images; std::vector<camera_frame_wo_image> camera_frame_wo_images; nvm_file input(FLAGS_nvm_file); all_images.resize(input.kf_data.size()); all_gray_images.resize(input.kf_data.size()); camera_frame_wo_images.resize(input.kf_data.size()); // TODO: Add distortion parameters for (int i=0; i<all_images.size(); i++) { std::cerr << FLAGS_data_dir + "/" + input.kf_data[i].filename << "\n"; all_images[i] = cv::imread(FLAGS_data_dir + "/" + input.kf_data[i].filename); cv::cvtColor(all_images[i], all_gray_images[i], CV_RGBA2GRAY); camera_frame_wo_images[i] = camera_frame_wo_image( input.kf_data[i].focal, input.kf_data[i].rotation, input.kf_data[i].translation, all_images[i].cols/2, all_images[i].rows/2); } // input.corr_data.clear(); cv::Point2f center(all_images[0].cols/2, all_images[0].rows/2); // for (int i=0; i<input.kf_data.size()-FLAGS_windows; i++) { for (int i=0; i<1; i++) { // Get good points in img i std::vector<cv::Point2f> corners; cv::goodFeaturesToTrack(all_gray_images[i], corners, maxCorners, qualityLevel, minDistance); std::cout << "Found " << corners.size() << "\n"; int c1= 0; for (auto pt: corners) { std::cout << c1 << "\n"; c1++; std::vector<triangulation_bundle> to_triangulate; // Get correspondances in img i+1 and i+2 ... to_triangulate.push_back(triangulation_bundle(camera_frame_wo_images[i], makeCenterSubtracted(pt, center))); cv::Point2f location; for (int j=i+1; j<i + FLAGS_windows; j++) { if (findPoint(pt, all_images[i], all_images[j], camera_frame_wo_images[i], camera_frame_wo_images[j], location)) { to_triangulate.push_back(triangulation_bundle(camera_frame_wo_images[j], makeCenterSubtracted(location, center))); } } // Triangulate if (to_triangulate.size()>2) { cv::Point3f final3d = Triangulate(to_triangulate); // Add to input 3D cloud input.corr_data.push_back(Corr3D(final3d, findColor(all_images[i], pt))); } } } input.save_to_disk(FLAGS_output_file); input.save_ply_file(FLAGS_output_ply); return 0; }
void MainWindow::refindmatch() { if (dm->scanSN == 0) dm->firstFind = true; findPoint(); }
void MainWindow::pointmatch() { dm->blocksize = ui->binarySlider->value(); findPoint(); }
/** * TODO es kommt auf die suchrichtung an, was direction==true oder false tut, ab dem winkel > 90 dreht sich die suchrichtung im Bild um. Veranschaulicht wird das durch einen Kreis wobei man in den beiden oberen Quadranten sucht. */ void Line::extend(bool direction DRAWDEBUG){ lms::math::vertex2i pixel; //std::cout<<"EXXXXXXXXXXXXTEND"<<std::endl; float searchStepX; float searchStepY; float currentLength = 0; float currentStepLength = m_LineParam.stepLengthMax; bool found = false; //search as long as the searchLength isn't reached while(currentLength < m_LineParam.maxLength){ found = false; //Create new point using the last data LinePoint searchPoint; if(direction){ searchPoint = m_points[m_points.size()-1]; }else{ searchPoint = m_points[0]; } //get needed stuff //float lineWidth = searchPoint.distance(); pixel.x = searchPoint.low_high.x; pixel.y = searchPoint.low_high.y; float oldSearchAngle = m_LineParam.searchAngle; float oldSearchAngleOrth; if(m_points.size() > 1){ //get angle between last two points EdgePoint *top; EdgePoint *bot; if(!m_LineParam.fixedSearchAngle){ if(direction){ top = &m_points[m_points.size()-1].low_high; bot = &m_points[m_points.size()-2].low_high; }else{ top = &m_points[1].low_high; bot = &m_points[0].low_high; } oldSearchAngle = atan2(top->y - bot->y,top->x-bot->x); oldSearchAngle -= M_PI_2; } } if(direction){ oldSearchAngleOrth = oldSearchAngle+M_PI_2; }else{ oldSearchAngleOrth = oldSearchAngle-M_PI_2; } //move the point along the tangent of the line and afterwards move it from the line so the point isn't already on the line searchStepX = cos(oldSearchAngleOrth)*currentStepLength-m_LineParam.lineWidthTransMultiplier*currentStepLength*cos(oldSearchAngle); searchStepY = sin(oldSearchAngleOrth)*currentStepLength-m_LineParam.lineWidthTransMultiplier*currentStepLength*sin(oldSearchAngle); //try to find a new point //calculate new searchPoint if(m_LineParam.target->inside(pixel.x+searchStepX,pixel.y+searchStepY)){ //move pixel pixel += lms::math::vertex2i(searchStepX,searchStepY); //TODO that could be made more efficient LinePoint::LinePointParam param = m_LineParam; param.x = pixel.x; param.y = pixel.y; param.searchLength = 2*m_LineParam.lineWidthTransMultiplier*currentStepLength; param.searchAngle = oldSearchAngle; if(findPoint(searchPoint,param DRAWDEBUG_ARG)){ found = true; if(direction){ currentLength += searchPoint.low_high.distance(m_points[m_points.size()-1].low_high); m_points.push_back(searchPoint); }else{ currentLength += searchPoint.low_high.distance(m_points[0].low_high); m_points.push_front(searchPoint); } } } //std::cout<<"FOUND "<<found<<" "<<currentLength<<std::endl; if(!found){ //found no point, decrease length //TODO add some better algo. currentStepLength *= 0.5; if(currentStepLength < m_LineParam.stepLengthMin){ //stop searching, no more points can be found on this line //TODO return //std::cout<<"BREAK "<<currentLength<<std::endl; break; } } } //std::cout<<"ENDE "<< currentLength<<" max: "<<m_LineParam.maxLength<<std::endl; }
/** * Function ConvertOutlineToPolygon * build a polygon (with holes) from a DRAWSEGMENT list, which is expected to be * a outline, therefore a closed main outline with perhaps closed inner outlines. * These closed inner outlines are considered as holes in the main outline * @param aSegList the initial list of drawsegments (only lines, circles and arcs). * @param aPolygons will contain the complex polygon. * @param aTolerance is the max distance between points that is still accepted as connected (internal units) * @param aErrorText is a wxString to return error message. * @param aErrorLocation is the optional position of the error in the outline */ bool ConvertOutlineToPolygon( std::vector<DRAWSEGMENT*>& aSegList, SHAPE_POLY_SET& aPolygons, wxString* aErrorText, unsigned int aTolerance, wxPoint* aErrorLocation ) { if( aSegList.size() == 0 ) return true; wxString msg; // Make a working copy of aSegList, because the list is modified during calculations std::vector< DRAWSEGMENT* > segList = aSegList; DRAWSEGMENT* graphic; wxPoint prevPt; // Find edge point with minimum x, this should be in the outer polygon // which will define the perimeter Edge.Cuts polygon. wxPoint xmin = wxPoint( INT_MAX, 0 ); int xmini = 0; for( size_t i = 0; i < segList.size(); i++ ) { graphic = (DRAWSEGMENT*) segList[i]; switch( graphic->GetShape() ) { case S_SEGMENT: { if( graphic->GetStart().x < xmin.x ) { xmin = graphic->GetStart(); xmini = i; } if( graphic->GetEnd().x < xmin.x ) { xmin = graphic->GetEnd(); xmini = i; } } break; case S_ARC: // Freerouter does not yet understand arcs, so approximate // an arc with a series of short lines and put those // line segments into the !same! PATH. { wxPoint pstart = graphic->GetArcStart(); wxPoint center = graphic->GetCenter(); double angle = -graphic->GetAngle(); double radius = graphic->GetRadius(); int steps = GetArcToSegmentCount( radius, ARC_LOW_DEF, angle / 10.0 ); wxPoint pt; for( int step = 1; step<=steps; ++step ) { double rotation = ( angle * step ) / steps; pt = pstart; RotatePoint( &pt, center, rotation ); if( pt.x < xmin.x ) { xmin = pt; xmini = i; } } } break; case S_CIRCLE: { wxPoint pt = graphic->GetCenter(); // pt has minimum x point pt.x -= graphic->GetRadius(); // when the radius <= 0, this is a mal-formed circle. Skip it if( graphic->GetRadius() > 0 && pt.x < xmin.x ) { xmin = pt; xmini = i; } } break; case S_CURVE: { graphic->RebuildBezierToSegmentsPointsList( graphic->GetWidth() ); for( unsigned int jj = 0; jj < graphic->GetBezierPoints().size(); jj++ ) { wxPoint pt = graphic->GetBezierPoints()[jj]; if( pt.x < xmin.x ) { xmin = pt; xmini = i; } } } break; case S_POLYGON: { const auto poly = graphic->GetPolyShape(); MODULE* module = aSegList[0]->GetParentModule(); double orientation = module ? module->GetOrientation() : 0.0; VECTOR2I offset = module ? module->GetPosition() : VECTOR2I( 0, 0 ); for( auto iter = poly.CIterate(); iter; iter++ ) { auto pt = *iter; RotatePoint( pt, orientation ); pt += offset; if( pt.x < xmin.x ) { xmin.x = pt.x; xmin.y = pt.y; xmini = i; } } } break; default: break; } } // Grab the left most point, assume its on the board's perimeter, and see if we // can put enough graphics together by matching endpoints to formulate a cohesive // polygon. graphic = (DRAWSEGMENT*) segList[xmini]; // The first DRAWSEGMENT is in 'graphic', ok to remove it from 'items' segList.erase( segList.begin() + xmini ); // Output the Edge.Cuts perimeter as circle or polygon. if( graphic->GetShape() == S_CIRCLE ) { int steps = GetArcToSegmentCount( graphic->GetRadius(), ARC_LOW_DEF, 360.0 ); TransformCircleToPolygon( aPolygons, graphic->GetCenter(), graphic->GetRadius(), steps ); } else if( graphic->GetShape() == S_POLYGON ) { MODULE* module = graphic->GetParentModule(); // NULL for items not in footprints double orientation = module ? module->GetOrientation() : 0.0; VECTOR2I offset = module ? module->GetPosition() : VECTOR2I( 0, 0 ); aPolygons.NewOutline(); for( auto it = graphic->GetPolyShape().CIterate( 0 ); it; it++ ) { auto pt = *it; RotatePoint( pt, orientation ); pt += offset; aPolygons.Append( pt ); } } else { // Polygon start point. Arbitrarily chosen end of the // segment and build the poly from here. wxPoint startPt = wxPoint( graphic->GetEnd() ); prevPt = graphic->GetEnd(); aPolygons.NewOutline(); aPolygons.Append( prevPt ); // Do not append the other end point yet of this 'graphic', this first // 'graphic' might be an arc or a curve. for(;;) { switch( graphic->GetShape() ) { case S_SEGMENT: { wxPoint nextPt; // Use the line segment end point furthest away from // prevPt as we assume the other end to be ON prevPt or // very close to it. if( close_st( prevPt, graphic->GetStart(), graphic->GetEnd() ) ) nextPt = graphic->GetEnd(); else nextPt = graphic->GetStart(); aPolygons.Append( nextPt ); prevPt = nextPt; } break; case S_ARC: // We do not support arcs in polygons, so approximate // an arc with a series of short lines and put those // line segments into the !same! PATH. { wxPoint pstart = graphic->GetArcStart(); wxPoint pend = graphic->GetArcEnd(); wxPoint pcenter = graphic->GetCenter(); double angle = -graphic->GetAngle(); double radius = graphic->GetRadius(); int steps = GetArcToSegmentCount( radius, ARC_LOW_DEF, angle / 10.0 ); if( !close_enough( prevPt, pstart, aTolerance ) ) { wxASSERT( close_enough( prevPt, graphic->GetArcEnd(), aTolerance ) ); angle = -angle; std::swap( pstart, pend ); } wxPoint nextPt; for( int step = 1; step<=steps; ++step ) { double rotation = ( angle * step ) / steps; nextPt = pstart; RotatePoint( &nextPt, pcenter, rotation ); aPolygons.Append( nextPt ); } prevPt = nextPt; } break; case S_CURVE: // We do not support Bezier curves in polygons, so approximate // with a series of short lines and put those // line segments into the !same! PATH. { wxPoint nextPt; bool reverse = false; // Use the end point furthest away from // prevPt as we assume the other end to be ON prevPt or // very close to it. if( close_st( prevPt, graphic->GetStart(), graphic->GetEnd() ) ) nextPt = graphic->GetEnd(); else { nextPt = graphic->GetStart(); reverse = true; } if( reverse ) { for( int jj = graphic->GetBezierPoints().size()-1; jj >= 0; jj-- ) aPolygons.Append( graphic->GetBezierPoints()[jj] ); } else { for( size_t jj = 0; jj < graphic->GetBezierPoints().size(); jj++ ) aPolygons.Append( graphic->GetBezierPoints()[jj] ); } prevPt = nextPt; } break; default: if( aErrorText ) { msg.Printf( "Unsupported DRAWSEGMENT type %s.", BOARD_ITEM::ShowShape( graphic->GetShape() ) ); *aErrorText << msg << "\n"; } if( aErrorLocation ) *aErrorLocation = graphic->GetPosition(); return false; } // Get next closest segment. graphic = findPoint( prevPt, segList, aTolerance ); // If there are no more close segments, check if the board // outline polygon can be closed. if( !graphic ) { if( close_enough( startPt, prevPt, aTolerance ) ) { // Close the polygon back to start point // aPolygons.Append( startPt ); // not needed } else { if( aErrorText ) { msg.Printf( _( "Unable to find segment with an endpoint of (%s, %s)." ), StringFromValue( MILLIMETRES, prevPt.x, true ), StringFromValue( MILLIMETRES, prevPt.y, true ) ); *aErrorText << msg << "\n"; } if( aErrorLocation ) *aErrorLocation = prevPt; return false; } break; } } } while( segList.size() ) { // emit a signal layers keepout for every interior polygon left... int hole = aPolygons.NewHole(); graphic = (DRAWSEGMENT*) segList[0]; segList.erase( segList.begin() ); // Both circles and polygons on the edge cuts layer are closed items that // do not connect to other elements, so we process them independently if( graphic->GetShape() == S_POLYGON ) { MODULE* module = graphic->GetParentModule(); // NULL for items not in footprints double orientation = module ? module->GetOrientation() : 0.0; VECTOR2I offset = module ? module->GetPosition() : VECTOR2I( 0, 0 ); for( auto it = graphic->GetPolyShape().CIterate(); it; it++ ) { auto val = *it; RotatePoint( val, orientation ); val += offset; aPolygons.Append( val, -1, hole ); } } else if( graphic->GetShape() == S_CIRCLE ) { // make a circle by segments; wxPoint center = graphic->GetCenter(); double angle = 3600.0; wxPoint start = center; int radius = graphic->GetRadius(); int steps = GetArcToSegmentCount( radius, ARC_LOW_DEF, 360.0 ); wxPoint nextPt; start.x += radius; for( int step = 0; step < steps; ++step ) { double rotation = ( angle * step ) / steps; nextPt = start; RotatePoint( &nextPt.x, &nextPt.y, center.x, center.y, rotation ); aPolygons.Append( nextPt, -1, hole ); } } else { // Polygon start point. Arbitrarily chosen end of the // segment and build the poly from here. wxPoint startPt( graphic->GetEnd() ); prevPt = graphic->GetEnd(); aPolygons.Append( prevPt, -1, hole ); // do not append the other end point yet, this first 'graphic' might be an arc for(;;) { switch( graphic->GetShape() ) { case S_SEGMENT: { wxPoint nextPt; // Use the line segment end point furthest away from // prevPt as we assume the other end to be ON prevPt or // very close to it. if( close_st( prevPt, graphic->GetStart(), graphic->GetEnd() ) ) { nextPt = graphic->GetEnd(); } else { nextPt = graphic->GetStart(); } prevPt = nextPt; aPolygons.Append( prevPt, -1, hole ); } break; case S_ARC: // Freerouter does not yet understand arcs, so approximate // an arc with a series of short lines and put those // line segments into the !same! PATH. { wxPoint pstart = graphic->GetArcStart(); wxPoint pend = graphic->GetArcEnd(); wxPoint pcenter = graphic->GetCenter(); double angle = -graphic->GetAngle(); int radius = graphic->GetRadius(); int steps = GetArcToSegmentCount( radius, ARC_LOW_DEF, angle / 10.0 ); if( !close_enough( prevPt, pstart, aTolerance ) ) { wxASSERT( close_enough( prevPt, graphic->GetArcEnd(), aTolerance ) ); angle = -angle; std::swap( pstart, pend ); } wxPoint nextPt; for( int step = 1; step <= steps; ++step ) { double rotation = ( angle * step ) / steps; nextPt = pstart; RotatePoint( &nextPt, pcenter, rotation ); aPolygons.Append( nextPt, -1, hole ); } prevPt = nextPt; } break; case S_CURVE: // We do not support Bezier curves in polygons, so approximate // with a series of short lines and put those // line segments into the !same! PATH. { wxPoint nextPt; bool reverse = false; // Use the end point furthest away from // prevPt as we assume the other end to be ON prevPt or // very close to it. if( close_st( prevPt, graphic->GetStart(), graphic->GetEnd() ) ) nextPt = graphic->GetEnd(); else { nextPt = graphic->GetStart(); reverse = true; } if( reverse ) { for( int jj = graphic->GetBezierPoints().size()-1; jj >= 0; jj-- ) aPolygons.Append( graphic->GetBezierPoints()[jj], -1, hole ); } else { for( size_t jj = 0; jj < graphic->GetBezierPoints().size(); jj++ ) aPolygons.Append( graphic->GetBezierPoints()[jj], -1, hole ); } prevPt = nextPt; } break; default: if( aErrorText ) { msg.Printf( "Unsupported DRAWSEGMENT type %s.", BOARD_ITEM::ShowShape( graphic->GetShape() ) ); *aErrorText << msg << "\n"; } if( aErrorLocation ) *aErrorLocation = graphic->GetPosition(); return false; } // Get next closest segment. graphic = findPoint( prevPt, segList, aTolerance ); // If there are no more close segments, check if polygon // can be closed. if( !graphic ) { if( close_enough( startPt, prevPt, aTolerance ) ) { // Close the polygon back to start point // aPolygons.Append( startPt, -1, hole ); // not needed } else { if( aErrorText ) { msg.Printf( _( "Unable to find segment with an endpoint of (%s, %s)." ), StringFromValue( MILLIMETRES, prevPt.x, true ), StringFromValue( MILLIMETRES, prevPt.y, true ) ); *aErrorText << msg << "\n"; } if( aErrorLocation ) *aErrorLocation = prevPt; return false; } break; } } } } return true; }