// directed (one end is wider than the other) vector<Poly> dir_thick_line(const Vector2d &from, const Vector2d &to, double fr_width, double to_width) { vector<Poly> p; if (fr_width < 0.001 || to_width < 0.001) return p; if (to.squared_distance(from) < 0.001) return p; if ((fr_width < 0) != (to_width < 0)) return p; Poly poly; Vector2d fdir = (to-from); fdir.normalize(); Vector2d tdir = fdir; fdir *= fr_width/4.; tdir *= to_width/4.; Vector2d fr_dirp(-fdir.y(), fdir.x()); Vector2d to_dirp(-tdir.y(), tdir.x()); poly.addVertex(from-fdir-fr_dirp); poly.addVertex(from-fdir+fr_dirp); poly.addVertex(to+tdir+to_dirp); poly.addVertex(to+tdir-to_dirp); p.push_back(poly); return p; //return Clipping::getOffset(poly, distance/4, jmiter, 0); // slow: // poly.addVertex(from); // poly.addVertex(to); // return Clipping::getOffset(poly, distance/2, jround, distance/2.); }
uint Poly::getFarthestIndex(const Vector2d &from) const { uint findex = 0; double maxdist = 0.; for (uint i = 0; i < size(); i++) { double d = from.squared_distance(vertices[i]); if (d > maxdist) { maxdist = d; findex = i; } } return findex; }
Vector2d Layer::getFarthestPolygonPoint(const Vector2d &from) const { if (polygons.size() == 0) return from; uint pindex = 0, pvindex = 0; double maxdist = 0.; for (uint i = 0; i<polygons.size(); i++) { uint fi = polygons[i].getFarthestIndex(from); double pdist = from.squared_distance(polygons[i][fi]); if (pdist > maxdist) { maxdist = pdist; pindex = i; pvindex = fi; } } return polygons[pindex][pvindex]; }
vector<Poly> thick_line(const Vector2d &from, const Vector2d &to, double width) { vector<Poly> p; if (width < 0.001) return p; if (to.squared_distance(from) < 0.001) return p; Poly poly; Vector2d dir = (to-from); dir.normalize(); dir *= width/4.; Vector2d dirp(-dir.y(),dir.x()); poly.addVertex(from-dir-dirp); poly.addVertex(from-dir+dirp); poly.addVertex(to+dir+dirp); poly.addVertex(to+dir-dirp); p.push_back(poly); return Clipping::getOffset(poly, width/4, jmiter, 0); // slow: // poly.addVertex(from); // poly.addVertex(to); // return Clipping::getOffset(poly, distance/2, jround, distance/2.); }
// find center for best fit of arcpoints bool fit_arc(const vector<Vector2d> &points, double sq_error, Vector2d &result_center, double &result_radiussq) { if (points.size() < 3) return false; const int n_par = 3; // center x,y and arc radius_sq // start values: const Vector2d P = points[0]; const Vector2d Q = points.back(); const Vector2d startxy = (P+Q)/2.; double par[3] = { startxy.x(), startxy.y(), P.squared_distance(Q) }; int m_dat = points.size(); arc_data_struct data; data.px = new double[m_dat]; data.py = new double[m_dat]; for (int i = 0; i < m_dat; i++) { data.px[i] = points[i].x(); data.py[i] = points[i].y(); } return fit_arc(m_dat, data, n_par, par, sq_error, result_center, result_radiussq); }