improve function RasterizeRectWithClearance, about 40% faster, ref #3588

This was SVN commit r17212.
This commit is contained in:
mimo
2015-11-09 21:16:46 +00:00
parent 35b0478f70
commit 51ec6f4728
+36 -11
View File
@@ -65,29 +65,54 @@ void SimRasterize::RasterizeRectWithClearance(Spans& spans,
// Find the min/max range of cells that are strictly inside the square+rasterClearance.
// (Since the square+rasterClearance is a convex shape, we can just test each
// corner of each cell is inside the shape.)
// (TODO: This potentially does a lot of redundant work.)
// When looping on i, if the previous cell was inside, no need to check again the left corners.
// and we can stop the loop when exiting the shape.
// Futhermore if one of the right corners of a cell is outside, no need to check the following cell
i16 spanI0 = std::numeric_limits<i16>::max();
i16 spanI1 = std::numeric_limits<i16>::min();
bool previousInside = false;
bool skipNextCell = false;
for (i16 i = i0; i < i1; ++i)
{
if (Geometry::DistanceToSquareSquared(CFixedVector2D(cellSize*i-shape.x, cellSize*j-shape.z),
shape.u, shape.v, shapeHalfSize, true) > rasterClearance)
if (skipNextCell)
{
skipNextCell = false;
continue;
}
if (Geometry::DistanceToSquareSquared(CFixedVector2D(cellSize*(i+1)-shape.x, cellSize*j-shape.z),
shape.u, shape.v, shapeHalfSize, true) > rasterClearance)
continue;
if (Geometry::DistanceToSquareSquared(CFixedVector2D(cellSize*i-shape.x, cellSize*(j+1)-shape.z),
shape.u, shape.v, shapeHalfSize, true) > rasterClearance)
shape.u, shape.v, shapeHalfSize, true) > rasterClearance)
{
if (previousInside)
break;
skipNextCell = true;
continue;
}
if (Geometry::DistanceToSquareSquared(CFixedVector2D(cellSize*(i+1)-shape.x, cellSize*(j+1)-shape.z),
shape.u, shape.v, shapeHalfSize, true) > rasterClearance)
shape.u, shape.v, shapeHalfSize, true) > rasterClearance)
{
if (previousInside)
break;
skipNextCell = true;
continue;
}
spanI0 = std::min(spanI0, i);
spanI1 = std::max(spanI1, (i16)(i+1));
if (!previousInside)
{
if (Geometry::DistanceToSquareSquared(CFixedVector2D(cellSize*i-shape.x, cellSize*j-shape.z),
shape.u, shape.v, shapeHalfSize, true) > rasterClearance)
continue;
if (Geometry::DistanceToSquareSquared(CFixedVector2D(cellSize*i-shape.x, cellSize*(j+1)-shape.z),
shape.u, shape.v, shapeHalfSize, true) > rasterClearance)
continue;
previousInside = true;
spanI0 = i;
}
spanI1 = i+1;
}
// Add non-empty spans onto the list