本文整理汇总了C++中PolygonRef::size方法的典型用法代码示例。如果您正苦于以下问题:C++ PolygonRef::size方法的具体用法?C++ PolygonRef::size怎么用?C++ PolygonRef::size使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类PolygonRef
的用法示例。
在下文中一共展示了PolygonRef::size方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: addPolygon
void GCodePlanner::addPolygon(PolygonRef polygon, int startIdx, GCodePathConfig* config, WallOverlapComputation* wall_overlap_computation)
{
Point p0 = polygon[startIdx];
addTravel(p0);
for(unsigned int i=1; i<polygon.size(); i++)
{
Point p1 = polygon[(startIdx + i) % polygon.size()];
addExtrusionMove(p1, config, (wall_overlap_computation)? wall_overlap_computation->getFlow(p0, p1) : 1.0);
p0 = p1;
}
if (polygon.size() > 2)
{
Point& p1 = polygon[startIdx];
addExtrusionMove(p1, config, (wall_overlap_computation)? wall_overlap_computation->getFlow(p0, p1) : 1.0);
}
}
示例2: calcScanlineCrossings
bool LinePolygonsCrossings::calcScanlineCrossings(bool fail_on_unavoidable_obstacles)
{
min_crossing_idx = NO_INDEX;
max_crossing_idx = NO_INDEX;
for(unsigned int poly_idx = 0; poly_idx < boundary.size(); poly_idx++)
{
PolyCrossings minMax(poly_idx);
PolygonRef poly = boundary[poly_idx];
Point p0 = transformation_matrix.apply(poly[poly.size() - 1]);
for(unsigned int point_idx = 0; point_idx < poly.size(); point_idx++)
{
Point p1 = transformation_matrix.apply(poly[point_idx]);
if ((p0.Y >= transformed_startPoint.Y && p1.Y <= transformed_startPoint.Y) || (p1.Y >= transformed_startPoint.Y && p0.Y <= transformed_startPoint.Y))
{ // if line segment crosses the line through the transformed start and end point (aka scanline)
if (p1.Y == p0.Y) //Line segment is parallel with the scanline. That means that both endpoints lie on the scanline, so they will have intersected with the adjacent line.
{
p0 = p1;
continue;
}
int64_t x = p0.X + (p1.X - p0.X) * (transformed_startPoint.Y - p0.Y) / (p1.Y - p0.Y); // intersection point between line segment and the scanline
if (x >= transformed_startPoint.X && x <= transformed_endPoint.X)
{
if (!((p1.Y == transformed_startPoint.Y && p1.Y < p0.Y) || (p0.Y == transformed_startPoint.Y && p0.Y < p1.Y)))
{ // perform edge case only for line segments on and below the scanline, not for line segments on and above.
// \/ will be no crossings and /\ two, but most importantly | will be one crossing.
minMax.n_crossings++;
}
if(x < minMax.min.x) //For the leftmost intersection, move x left to stay outside of the border.
//Note: The actual distance from the intersection to the border is almost always less than dist_to_move_boundary_point_outside, since it only moves along the direction of the scanline.
{
minMax.min.x = x;
minMax.min.point_idx = point_idx;
}
if(x > minMax.max.x) //For the rightmost intersection, move x right to stay outside of the border.
{
minMax.max.x = x;
minMax.max.point_idx = point_idx;
}
}
}
p0 = p1;
}
if (fail_on_unavoidable_obstacles && minMax.n_crossings % 2 == 1)
{ // if start area and end area are not the same
return false;
}
else if (minMax.min.point_idx != NO_INDEX) // then always also max.point_idx != NO_INDEX
{ // if this polygon crossed the scanline
if (min_crossing_idx == NO_INDEX || minMax.min.x < crossings[min_crossing_idx].min.x) { min_crossing_idx = crossings.size(); }
if (max_crossing_idx == NO_INDEX || minMax.max.x > crossings[max_crossing_idx].max.x) { max_crossing_idx = crossings.size(); }
crossings.push_back(minMax);
}
}
return true;
}
示例3: handleWallStruts
void AreaSupport::handleWallStruts(
Polygons& supportLayer_this,
int supportMinAreaSqrt,
int supportTowerDiameter
)
{
for (unsigned int p = 0; p < supportLayer_this.size(); p++)
{
PolygonRef poly = supportLayer_this[p];
if (poly.size() < 6) // might be a single wall
{
PolygonRef poly = supportLayer_this[p];
int best = -1;
int best_length2 = -1;
for (unsigned int i = 0; i < poly.size(); i++)
{
int length2 = vSize2(poly[i] - poly[(i+1) % poly.size()]);
if (length2 > best_length2)
{
best = i;
best_length2 = length2;
}
}
if (best_length2 < supportMinAreaSqrt * supportMinAreaSqrt)
break; // this is a small area, not a wall!
// an estimate of the width of the area
int width = sqrt( poly.area() * poly.area() / best_length2 ); // sqrt (a^2 / l^2) instead of a / sqrt(l^2)
// add square tower (strut) in the middle of the wall
if (width < supportMinAreaSqrt)
{
Point mid = (poly[best] + poly[(best+1) % poly.size()] ) / 2;
Polygons struts;
PolygonRef strut = struts.newPoly();
strut.add(mid + Point( supportTowerDiameter/2, supportTowerDiameter/2));
strut.add(mid + Point(-supportTowerDiameter/2, supportTowerDiameter/2));
strut.add(mid + Point(-supportTowerDiameter/2, -supportTowerDiameter/2));
strut.add(mid + Point( supportTowerDiameter/2, -supportTowerDiameter/2));
supportLayer_this = supportLayer_this.unionPolygons(struts);
}
}
}
}
示例4: dumpSegmentsToHTML
void Slicer::dumpSegmentsToHTML(const char* filename)
{
float scale = std::max(modelSize.x, modelSize.y) / 1500;
FILE* f = fopen(filename, "w");
fprintf(f, "<!DOCTYPE html><html><body>\n");
for(unsigned int i=0; i<layers.size(); i++)
{
fprintf(f, "<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" style='width:%ipx;height:%ipx'>\n", int(modelSize.x / scale), int(modelSize.y / scale));
fprintf(f, "<marker id='MidMarker' viewBox='0 0 10 10' refX='5' refY='5' markerUnits='strokeWidth' markerWidth='10' markerHeight='10' stroke='lightblue' stroke-width='2' fill='none' orient='auto'>");
fprintf(f, "<path d='M 0 0 L 10 5 M 0 10 L 10 5'/>");
fprintf(f, "</marker>");
fprintf(f, "<g fill-rule='evenodd' style=\"fill: gray; stroke:black;stroke-width:1\">\n");
fprintf(f, "<path marker-mid='url(#MidMarker)' d=\"");
for(unsigned int j=0; j<layers[i].polygonList.size(); j++)
{
PolygonRef p = layers[i].polygonList[j];
for(unsigned int n=0; n<p.size(); n++)
{
if (n == 0)
fprintf(f, "M");
else
fprintf(f, "L");
fprintf(f, "%f,%f ", float(p[n].X - modelMin.x)/scale, float(p[n].Y - modelMin.y)/scale);
}
fprintf(f, "Z\n");
}
fprintf(f, "\"/>");
fprintf(f, "</g>\n");
for(unsigned int j=0; j<layers[i].openPolygonList.size(); j++)
{
PolygonRef p = layers[i].openPolygonList[j];
if (p.size() < 1) continue;
fprintf(f, "<polyline marker-mid='url(#MidMarker)' points=\"");
for(unsigned int n=0; n<p.size(); n++)
{
fprintf(f, "%f,%f ", float(p[n].X - modelMin.x)/scale, float(p[n].Y - modelMin.y)/scale);
}
fprintf(f, "\" style=\"fill: none; stroke:red;stroke-width:1\" />\n");
}
fprintf(f, "</svg>\n");
}
fprintf(f, "</body></html>");
fclose(f);
}
示例5: getClosestPointInPolygon
inline int PathOrderOptimizer::getClosestPointInPolygon(Point prev_point, int i_polygon)
{
PolygonRef poly = polygons[i_polygon];
int best = -1;
float bestDist = std::numeric_limits<float>::infinity();
bool orientation = poly.orientation();
for(unsigned int i_point=0 ; i_point<poly.size() ; i_point++)
{
float dist = vSize2f(poly[i_point] - prev_point);
Point n0 = normal(poly[(i_point-1+poly.size())%poly.size()] - poly[i_point], 2000);
Point n1 = normal(poly[i_point] - poly[(i_point + 1) % poly.size()], 2000);
float dot_score = dot(n0, n1) - dot(crossZ(n0), n1); /// prefer binnenbocht
if (orientation)
dot_score = -dot_score;
if (dist + dot_score < bestDist)
{
best = i_point;
bestDist = dist;
}
}
return best;
}
示例6: getClosestPointInPolygon
int PathOrderOptimizer::getClosestPointInPolygon(Point prev_point, int poly_idx)
{
PolygonRef poly = polygons[poly_idx];
int best_point_idx = -1;
float best_point_score = std::numeric_limits<float>::infinity();
Point p0 = poly.back();
for (unsigned int point_idx = 0; point_idx < poly.size(); point_idx++)
{
Point& p1 = poly[point_idx];
Point& p2 = poly[(point_idx + 1) % poly.size()];
int64_t dist = vSize2(p1 - prev_point);
float is_on_inside_corner_score = -LinearAlg2D::getAngleLeft(p0, p1, p2) / M_PI * 5000 * 5000; // prefer inside corners
// this score is in the order of 5 mm
if (dist + is_on_inside_corner_score < best_point_score)
{
best_point_idx = point_idx;
best_point_score = dist + is_on_inside_corner_score;
}
p0 = p1;
}
return best_point_idx;
}
示例7: calcScanlineCrossings
void LinePolygonsCrossings::calcScanlineCrossings()
{
min_crossing_idx = NO_INDEX;
max_crossing_idx = NO_INDEX;
for(unsigned int poly_idx = 0; poly_idx < boundary.size(); poly_idx++)
{
PolyCrossings minMax(poly_idx);
PolygonRef poly = boundary[poly_idx];
Point p0 = transformation_matrix.apply(poly[poly.size() - 1]);
for(unsigned int point_idx = 0; point_idx < poly.size(); point_idx++)
{
Point p1 = transformation_matrix.apply(poly[point_idx]);
if((p0.Y >= transformed_startPoint.Y && p1.Y <= transformed_startPoint.Y) || (p1.Y >= transformed_startPoint.Y && p0.Y <= transformed_startPoint.Y))
{
if(p1.Y == p0.Y) //Line segment is parallel with the scanline. That means that both endpoints lie on the scanline, so they will have intersected with the adjacent line.
{
p0 = p1;
continue;
}
int64_t x = p0.X + (p1.X - p0.X) * (transformed_startPoint.Y - p0.Y) / (p1.Y - p0.Y);
if (x >= transformed_startPoint.X && x <= transformed_endPoint.X)
{
if(x < minMax.min.x) //For the leftmost intersection, move x left to stay outside of the border.
//Note: The actual distance from the intersection to the border is almost always less than dist_to_move_boundary_point_outside, since it only moves along the direction of the scanline.
{
minMax.min.x = x;
minMax.min.point_idx = point_idx;
}
if(x > minMax.max.x) //For the rightmost intersection, move x right to stay outside of the border.
{
minMax.max.x = x;
minMax.max.point_idx = point_idx;
}
}
}
p0 = p1;
}
if (minMax.min.point_idx != NO_INDEX)
{ // then also max.point_idx != -1
if (min_crossing_idx == NO_INDEX || minMax.min.x < crossings[min_crossing_idx].min.x) { min_crossing_idx = crossings.size(); }
if (max_crossing_idx == NO_INDEX || minMax.max.x > crossings[max_crossing_idx].max.x) { max_crossing_idx = crossings.size(); }
crossings.push_back(minMax);
}
}
}
示例8: calcScanlineCrossings
void LinePolygonsCrossings::calcScanlineCrossings()
{
min_crossing_idx = NO_INDEX;
max_crossing_idx = NO_INDEX;
for(unsigned int poly_idx = 0; poly_idx < boundary.size(); poly_idx++)
{
PolyCrossings minMax(poly_idx);
PolygonRef poly = boundary[poly_idx];
Point p0 = transformation_matrix.apply(poly.back());
for(unsigned int point_idx = 0; point_idx < poly.size(); point_idx++)
{
Point p1 = transformation_matrix.apply(poly[point_idx]);
if ((p0.Y > transformed_startPoint.Y && p1.Y < transformed_startPoint.Y) || (p1.Y > transformed_startPoint.Y && p0.Y < transformed_startPoint.Y))
{
int64_t x = p0.X + (p1.X - p0.X) * (transformed_startPoint.Y - p0.Y) / (p1.Y - p0.Y);
if (x >= transformed_startPoint.X && x <= transformed_endPoint.X)
{
if (x < minMax.min.x) { minMax.min.x = x; minMax.min.point_idx = point_idx; }
if (x > minMax.max.x) { minMax.max.x = x; minMax.max.point_idx = point_idx; }
}
}
p0 = p1;
}
if (minMax.min.point_idx != NO_INDEX)
{ // then also max.point_idx != -1
if (min_crossing_idx == NO_INDEX || minMax.min.x < crossings[min_crossing_idx].min.x) { min_crossing_idx = crossings.size(); }
if (max_crossing_idx == NO_INDEX || minMax.max.x > crossings[max_crossing_idx].max.x) { max_crossing_idx = crossings.size(); }
crossings.push_back(minMax);
}
}
}
示例9: optimize
void PathOrderOptimizer::optimize()
{
bool* picked=new bool[polygons.size()];
// bool picked[polygons.size()];
memset(picked, false, sizeof(bool) * polygons.size());/// initialized as falses
for(unsigned int i_polygon=0 ; i_polygon<polygons.size() ; i_polygon++) /// find closest point to initial starting point within each polygon +initialize picked
{
int best = -1;
float bestDist = std::numeric_limits<float>::infinity();
PolygonRef poly = polygons[i_polygon];
for(unsigned int i_point=0; i_point<poly.size(); i_point++) /// get closest point in polygon
{
float dist = vSize2f(poly[i_point] - startPoint);
if (dist < bestDist)
{
best = i_point;
bestDist = dist;
}
}
polyStart.push_back(best);
//picked.push_back(false); /// initialize all picked values as false
assert(poly.size() != 2);
}
Point prev_point = startPoint;
for(unsigned int i_polygon=0 ; i_polygon<polygons.size() ; i_polygon++) /// actual path order optimizer
{
int best = -1;
float bestDist = std::numeric_limits<float>::infinity();
for(unsigned int i_polygon=0 ; i_polygon<polygons.size() ; i_polygon++)
{
if (picked[i_polygon] || polygons[i_polygon].size() < 1) /// skip single-point-polygons
continue;
assert (polygons[i_polygon].size() != 2);
float dist = vSize2f(polygons[i_polygon][polyStart[i_polygon]] - prev_point);
if (dist < bestDist)
{
best = i_polygon;
bestDist = dist;
}
}
if (best > -1) /// should always be true; we should have been able to identify the best next polygon
{
assert(polygons[best].size() != 2);
prev_point = polygons[best][polyStart[best]];
picked[best] = true;
polyOrder.push_back(best);
}
else
logError("Failed to find next closest polygon.\n");
}
prev_point = startPoint;
for(unsigned int n=0; n<polyOrder.size(); n++) /// decide final starting points in each polygon
{
int i_polygon = polyOrder[n];
int best = getClosestPointInPolygon(prev_point, i_polygon);
polyStart[i_polygon] = best;
prev_point = polygons[i_polygon][best];
}
}
示例10: optimize
void PathOrderOptimizer::optimize()
{
std::vector<bool> picked;
for(unsigned int i=0;i<polygons.size(); i++)
{
int best = -1;
float bestDist = 0xFFFFFFFFFFFFFFFFLL;
PolygonRef poly = polygons[i];
for(unsigned int j=0; j<poly.size(); j++)
{
float dist = vSize2f(poly[j] - startPoint);
if (dist < bestDist)
{
best = j;
bestDist = dist;
}
}
polyStart.push_back(best);
picked.push_back(false);
}
Point p0 = startPoint;
for(unsigned int n=0; n<polygons.size(); n++)
{
int best = -1;
float bestDist = 0xFFFFFFFFFFFFFFFFLL;
for(unsigned int i=0;i<polygons.size(); i++)
{
if (picked[i] || polygons[i].size() < 1)
continue;
if (polygons[i].size() == 2)
{
float dist = vSize2f(polygons[i][0] - p0);
if (dist < bestDist)
{
best = i;
bestDist = dist;
polyStart[i] = 0;
}
dist = vSize2f(polygons[i][1] - p0);
if (dist < bestDist)
{
best = i;
bestDist = dist;
polyStart[i] = 1;
}
}else{
float dist = vSize2f(polygons[i][polyStart[i]] - p0);
if (dist < bestDist)
{
best = i;
bestDist = dist;
}
}
}
if (best > -1)
{
if (polygons[best].size() == 2)
{
p0 = polygons[best][(polyStart[best] + 1) % 2];
}else{
p0 = polygons[best][polyStart[best]];
}
picked[best] = true;
polyOrder.push_back(best);
}
}
p0 = startPoint;
for(unsigned int n=0; n<polyOrder.size(); n++)
{
int nr = polyOrder[n];
int best = -1;
float bestDist = 0xFFFFFFFFFFFFFFFFLL;
for(unsigned int i=0;i<polygons[nr].size(); i++)
{
float dist = vSize2f(polygons[nr][i] - p0);
if (dist < bestDist)
{
best = i;
bestDist = dist;
}
}
polyStart[nr] = best;
if (polygons[nr].size() <= 2)
{
p0 = polygons[nr][(best + 1) % 2];
}else{
p0 = polygons[nr][best];
}
}
}
示例11: generateLinearBasedInfill
/*
* algorithm:
* 1. for each line segment of each polygon:
* store the intersections of that line segment with all scanlines in a mapping (vector of vectors) from scanline to intersections
* (zigzag): add boundary segments to result
* 2. for each scanline:
* sort the associated intersections
* and connect them using the even-odd rule
*
* rough explanation of the zigzag algorithm:
* while walking around (each) polygon (1.)
* if polygon intersects with even scanline
* start boundary segment (add each following segment to the [result])
* when polygon intersects with a scanline again
* stop boundary segment (stop adding segments to the [result])
* (see infill/ZigzagConnectorProcessor.h for actual implementation details)
*
*
* we call the areas between two consecutive scanlines a 'scansegment'.
* Scansegment x is the area between scanline x and scanline x+1
* Edit: the term scansegment is wrong, since I call a boundary segment leaving from an even scanline to the left as belonging to an even scansegment,
* while I also call a boundary segment leaving from an even scanline toward the right as belonging to an even scansegment.
*/
void Infill::generateLinearBasedInfill(const int outline_offset, Polygons& result, const int line_distance, const PointMatrix& rotation_matrix, ZigzagConnectorProcessor& zigzag_connector_processor, const bool connected_zigzags, int64_t extra_shift)
{
if (line_distance == 0)
{
return;
}
if (in_outline.size() == 0)
{
return;
}
int shift = extra_shift + this->shift;
Polygons outline;
if (outline_offset != 0)
{
outline = in_outline.offset(outline_offset);
if (perimeter_gaps)
{
perimeter_gaps->add(in_outline.difference(outline.offset(infill_line_width / 2 + perimeter_gaps_extra_offset)));
}
}
else
{
outline = in_outline;
}
outline = outline.offset(infill_overlap);
if (outline.size() == 0)
{
return;
}
outline.applyMatrix(rotation_matrix);
if (shift < 0)
{
shift = line_distance - (-shift) % line_distance;
}
else
{
shift = shift % line_distance;
}
AABB boundary(outline);
int scanline_min_idx = computeScanSegmentIdx(boundary.min.X - shift, line_distance);
int line_count = computeScanSegmentIdx(boundary.max.X - shift, line_distance) + 1 - scanline_min_idx;
std::vector<std::vector<int64_t> > cut_list; // mapping from scanline to all intersections with polygon segments
for(int scanline_idx = 0; scanline_idx < line_count; scanline_idx++)
{
cut_list.push_back(std::vector<int64_t>());
}
for(unsigned int poly_idx = 0; poly_idx < outline.size(); poly_idx++)
{
PolygonRef poly = outline[poly_idx];
Point p0 = poly.back();
zigzag_connector_processor.registerVertex(p0); // always adds the first point to ZigzagConnectorProcessorEndPieces::first_zigzag_connector when using a zigzag infill type
for(unsigned int point_idx = 0; point_idx < poly.size(); point_idx++)
{
Point p1 = poly[point_idx];
if (p1.X == p0.X)
{
zigzag_connector_processor.registerVertex(p1);
// TODO: how to make sure it always adds the shortest line? (in order to prevent overlap with the zigzag connectors)
// note: this is already a problem for normal infill, but hasn't really cothered anyone so far.
p0 = p1;
continue;
}
int scanline_idx0;
int scanline_idx1;
// this way of handling the indices takes care of the case where a boundary line segment ends exactly on a scanline:
//.........这里部分代码省略.........
示例12: moveInside
unsigned int moveInside(Polygons& polygons, Point& from, int distance, int64_t maxDist2)
{
Point ret = from;
int64_t bestDist2 = maxDist2;
unsigned int bestPoly = NO_INDEX;
for (unsigned int poly_idx = 0; poly_idx < polygons.size(); poly_idx++)
{
PolygonRef poly = polygons[poly_idx];
if (poly.size() < 2)
continue;
Point p0 = poly[poly.size()-2];
Point p1 = poly.back();
bool projected_p_beyond_prev_segment = dot(p1 - p0, from - p0) > vSize2(p1 - p0);
for(Point& p2 : poly)
{
// X = A + Normal( B - A ) * ((( B - A ) dot ( P - A )) / VSize( A - B ));
// X = P projected on AB
Point& a = p1;
Point& b = p2;
Point& p = from;
Point ab = b - a;
Point ap = p - a;
int64_t ab_length = vSize(ab);
int64_t ax_length = dot(ab, ap) / ab_length;
if (ax_length < 0) // x is projected to before ab
{
if (projected_p_beyond_prev_segment)
{ // case which looks like: > .
projected_p_beyond_prev_segment = false;
Point& x = p1;
int64_t dist2 = vSize2(x - p);
if (dist2 < bestDist2)
{
bestDist2 = dist2;
if (distance == 0) { ret = x; }
else { ret = x + normal(crossZ(normal(a, distance*4) + normal(p1 - p0, distance*4)), distance); } // *4 to retain more precision for the eventual normalization
bestPoly = poly_idx;
}
}
else
{
projected_p_beyond_prev_segment = false;
p0 = p1;
p1 = p2;
continue;
}
}
else if (ax_length > ab_length) // x is projected to beyond ab
{
projected_p_beyond_prev_segment = true;
p0 = p1;
p1 = p2;
continue;
}
else
{
projected_p_beyond_prev_segment = false;
Point x = a + ab * ax_length / ab_length;
int64_t dist2 = vSize2(x - from);
if (dist2 < bestDist2)
{
bestDist2 = dist2;
if (distance == 0) { ret = x; }
else { ret = x + crossZ(normal(ab, distance)); }
bestPoly = poly_idx;
}
}
p0 = p1;
p1 = p2;
}
}
if (bestDist2 < maxDist2)
{
from = ret;
return bestPoly;
}
return NO_INDEX;
}
示例13: getNextPointWithDistance
bool getNextPointWithDistance(Point from, int64_t dist, const PolygonRef poly, int start_idx, int poly_start_idx, GivenDistPoint& result)
{
Point prev_poly_point = poly[(start_idx + poly_start_idx) % poly.size()];
for (unsigned int prev_idx = start_idx; prev_idx < poly.size(); prev_idx++)
{
int next_idx = (prev_idx + 1 + poly_start_idx) % poly.size(); // last checked segment is between last point in poly and poly[0]...
Point& next_poly_point = poly[next_idx];
if ( !shorterThen(next_poly_point - from, dist) )
{
/*
* x r
* p.---------+---+------------.n
* L| /
* | / dist
* |/
* f.
*
* f=from
* p=prev_poly_point
* n=next_poly_point
* x= f projected on pn
* r=result point at distance [dist] from f
*/
Point pn = next_poly_point - prev_poly_point;
if (shorterThen(pn, 100)) // when precision is limited
{
Point middle = (next_poly_point + prev_poly_point) / 2;
int64_t dist_to_middle = vSize(from - middle);
if (dist_to_middle - dist < 100 && dist_to_middle - dist > -100)
{
result.location = middle;
result.pos = prev_idx;
return true;
} else
{
prev_poly_point = next_poly_point;
continue;
}
}
Point pf = from - prev_poly_point;
Point px = dot(pf, pn) / vSize(pn) * pn / vSize(pn);
Point xf = pf - px;
if (!shorterThen(xf, dist)) // line lies wholly further than pn
{
prev_poly_point = next_poly_point;
continue;
}
int64_t xr_dist = std::sqrt(dist*dist - vSize2(xf)); // inverse Pythagoras
if (vSize(pn - px) - xr_dist < 1) // r lies beyond n
{
prev_poly_point = next_poly_point;
continue;
}
Point xr = xr_dist * pn / vSize(pn);
Point pr = px + xr;
result.location = prev_poly_point + pr;
result.pos = prev_idx;
return true;
}
prev_poly_point = next_poly_point;
}
return false;
}
示例14: optimize
void LineOrderOptimizer::optimize()
{
int gridSize = 5000; // the size of the cells in the hash grid. TODO
SparsePointGridInclusive<unsigned int> line_bucket_grid(gridSize);
bool picked[polygons.size()];
memset(picked, false, sizeof(bool) * polygons.size());/// initialized as falses
for (unsigned int poly_idx = 0; poly_idx < polygons.size(); poly_idx++) /// find closest point to initial starting point within each polygon +initialize picked
{
int best_point_idx = -1;
float best_point_dist = std::numeric_limits<float>::infinity();
PolygonRef poly = polygons[poly_idx];
for (unsigned int point_idx = 0; point_idx < poly.size(); point_idx++) /// get closest point from polygon
{
float dist = vSize2f(poly[point_idx] - startPoint);
if (dist < best_point_dist)
{
best_point_idx = point_idx;
best_point_dist = dist;
}
}
polyStart.push_back(best_point_idx);
assert(poly.size() == 2);
line_bucket_grid.insert(poly[0], poly_idx);
line_bucket_grid.insert(poly[1], poly_idx);
}
Point incoming_perpundicular_normal(0, 0);
Point prev_point = startPoint;
for (unsigned int order_idx = 0; order_idx < polygons.size(); order_idx++) /// actual path order optimizer
{
int best_line_idx = -1;
float best_score = std::numeric_limits<float>::infinity(); // distance score for the best next line
/// check if single-line-polygon is close to last point
for(unsigned int close_line_idx :
line_bucket_grid.getNearbyVals(prev_point, gridSize))
{
if (picked[close_line_idx] || polygons[close_line_idx].size() < 1)
{
continue;
}
updateBestLine(close_line_idx, best_line_idx, best_score, prev_point, incoming_perpundicular_normal);
}
if (best_line_idx == -1) /// if single-line-polygon hasn't been found yet
{
for (unsigned int poly_idx = 0; poly_idx < polygons.size(); poly_idx++)
{
if (picked[poly_idx] || polygons[poly_idx].size() < 1) /// skip single-point-polygons
{
continue;
}
assert(polygons[poly_idx].size() == 2);
updateBestLine(poly_idx, best_line_idx, best_score, prev_point, incoming_perpundicular_normal);
}
}
if (best_line_idx > -1) /// should always be true; we should have been able to identify the best next polygon
{
PolygonRef best_line = polygons[best_line_idx];
assert(best_line.size() == 2);
int line_start_point_idx = polyStart[best_line_idx];
int line_end_point_idx = line_start_point_idx * -1 + 1; /// 1 -> 0 , 0 -> 1
Point& line_start = best_line[line_start_point_idx];
Point& line_end = best_line[line_end_point_idx];
prev_point = line_end;
incoming_perpundicular_normal = turn90CCW(normal(line_end - line_start, 1000));
picked[best_line_idx] = true;
polyOrder.push_back(best_line_idx);
}
else
{
logError("Failed to find next closest line.\n");
}
}
}
示例15: optimize
void PathOrderOptimizer::optimize()
{
const float incommingPerpundicularNormalScale = 0.0001f;
std::map<uint32_t, std::vector<unsigned int>> location_to_polygon_map;
std::vector<bool> picked;
for(unsigned int i=0; i<polygons.size(); i++)
{
int best = -1;
float bestDist = 0xFFFFFFFFFFFFFFFFLL;
PolygonRef poly = polygons[i];
for(unsigned int j=0; j<poly.size(); j++)
{
float dist = vSize2f(poly[j] - startPoint);
if (dist < bestDist)
{
best = j;
bestDist = dist;
}
}
polyStart.push_back(best);
picked.push_back(false);
if (poly.size() == 2)
{
Point p0 = poly[0];
Point p1 = poly[1];
location_to_polygon_map[hashPoint(p0)].push_back(i);
location_to_polygon_map[hashPoint(p1)].push_back(i);
}
}
Point incommingPerpundicularNormal(0, 0);
Point p0 = startPoint;
for(unsigned int n=0; n<polygons.size(); n++)
{
int best = -1;
float bestDist = 0xFFFFFFFFFFFFFFFFLL;
for(unsigned int i : location_to_polygon_map[hashPoint(p0)])
{
if (picked[i] || polygons[i].size() < 1)
continue;
float dist = vSize2f(polygons[i][0] - p0);
dist += abs(dot(incommingPerpundicularNormal, normal(polygons[i][1] - polygons[i][0], 1000))) * incommingPerpundicularNormalScale;
if (dist < bestDist)
{
best = i;
bestDist = dist;
polyStart[i] = 0;
}
dist = vSize2f(polygons[i][1] - p0);
dist += abs(dot(incommingPerpundicularNormal, normal(polygons[i][0] - polygons[i][1], 1000))) * incommingPerpundicularNormalScale;
if (dist < bestDist)
{
best = i;
bestDist = dist;
polyStart[i] = 1;
}
}
if (best == -1)
{
for(unsigned int i=0; i<polygons.size(); i++)
{
if (picked[i] || polygons[i].size() < 1)
continue;
if (polygons[i].size() == 2)
{
float dist = vSize2f(polygons[i][0] - p0);
dist += abs(dot(incommingPerpundicularNormal, normal(polygons[i][1] - polygons[i][0], 1000))) * incommingPerpundicularNormalScale;
if (dist < bestDist)
{
best = i;
bestDist = dist;
polyStart[i] = 0;
}
dist = vSize2f(polygons[i][1] - p0);
dist += abs(dot(incommingPerpundicularNormal, normal(polygons[i][0] - polygons[i][1], 1000))) * incommingPerpundicularNormalScale;
if (dist < bestDist)
{
best = i;
bestDist = dist;
polyStart[i] = 1;
}
} else {
float dist = vSize2f(polygons[i][polyStart[i]] - p0);
if (dist < bestDist)
{
best = i;
bestDist = dist;
}
}
}
}
if (best > -1)
{
if (polygons[best].size() == 2)
//.........这里部分代码省略.........