BUG: Backport BresenhamLine integer-only algorithm and double precision fix#6054
Conversation
|
| Filename | Overview |
|---|---|
| Modules/Core/Common/include/itkBresenhamLine.hxx | Two backported bug fixes: integer-only Bresenham for BuildLine(Index,Index) and double-precision variable for BuildLine(Direction,length); logic is correct but the float→double precision improvement in the division on line 44 is incomplete due to LType using float components |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["BuildLine(Direction, length)"] --> B["Normalize direction"]
B --> C["Find dominant axis (max |component|)"]
C --> D["Compute euclideanLineLen = (length-1) / |Direction[mainAxis]| as double"]
D --> E["Compute LastIndex: double × float → double, RoundHalfIntegerUp"]
E --> F["Call BuildLine(StartIndex, LastIndex)"]
F --> G["Convert IndexArray → OffsetArray"]
H["BuildLine(p0, p1)"] --> I["Compute absDeltas and step (integer only)"]
I --> J["Find mainAxis (max |delta|)"]
J --> K["numPixels = maxAbsDelta + 1"]
K --> L{"For s = 0..numPixels-1"}
L --> M["Push currentIndex"]
M --> N["Advance main axis by step[mainAxis]"]
N --> O["Each secondary axis: accumulate 2×absDelta; if ≥ maxAbsDelta → step, subtract 2×maxAbsDelta"]
O --> L
L -->|done| P["Return IndexArray guaranteed to end at p1"]
Reviews (1): Last reviewed commit: "BUG: BresenhamLine - use double precisio..." | Re-trigger Greptile
53bfa9c to
f6d2be5
Compare
Replace the floating-point delegation through BuildLine(Direction,
length) with a direct integer-only N-dimensional Bresenham that
guarantees exact start and end points by construction.
The previous implementation converted integer endpoints to a
floating-point direction vector, computed Chebyshev distance for
the line length, then reconstructed LastIndex via rounding. This
introduced endpoint error for lines where the dominant-axis
projection differed from the Euclidean length (e.g., {0,0,0} to
{250,250,1} would overshoot to {251,251,0}).
Reference: classic Bresenham extended to N-D as used by scikit-image
(line_nd), OpenCV (LineIterator), and VTK (vtkLine).
(cherry picked from commit 59e3c06)
…putation Use explicit static_cast<double>() on both operands of the division computing euclideanLineLen so the division evaluates in double precision, not float (LType = Vector<float>). Assisted-by: Greptile — identified float-precision division in BuildLine (cherry picked from commit b7248b1)
f6d2be5 to
2003fb4
Compare
22f6d27
into
InsightSoftwareConsortium:release-5.4
Backport two BresenhamLine bug fixes from
maintorelease-5.4. Part of #6051.59e3c069— Integer-only N-dimensional Bresenham forBuildLine(Index, Index), avoiding floating-point direction conversion entirelyb7248b1c— Usedoubleprecision (notfloat) for ending index computation inBuildLine(Direction, length)Cherry-pick adaptation
Required one API adaptation:
itk::Math::Absolute()does not exist on release-5.4 (added on main as part of Math modernization). Replaced withitk::Math::abs()which is the release-5.4 equivalent.Local build verified: compiles cleanly with the Path and Voronoi modules enabled.