@@ -146,20 +146,6 @@ public PositionList createTiles(double overlap, OverlapUnitEnum overlapUnit,
146146 return null ;
147147 }
148148
149- double totalSizeXUm = nrImagesX * tileSizeXUm + overlapXUm ;
150- double totalSizeYUm = nrImagesY * tileSizeYUm + overlapYUm ;
151-
152- // Since an evenly spaced grid will likely not perfectly fit the bounding box
153- // that was specified we use this offset so that our grid is still centered properly.
154- // This slightly widens the field that is scanned. Sometime this can result in setting
155- // a position that is outside of the stage's range of motion. This causes issues when
156- // it comes time to stitch.
157- // This approach could also result in damage if the user specified a region that is
158- // near something delicate and then this code expands that range. It may be good to
159- // try a different approach.
160- double offsetXUm = (totalSizeXUm - boundingXUm ) / 2 ;
161- double offsetYUm = (totalSizeYUm - boundingYUm ) / 2 ;
162-
163149 // Compute per-tile step vectors in stage space.
164150 // With an affine transform, moving one tile to the right in camera-pixel space
165151 // corresponds to affine * (tileWidthPx, 0) in stage microns — not simply
@@ -188,9 +174,13 @@ public PositionList createTiles(double overlap, OverlapUnitEnum overlapUnit,
188174 stepYdy = tileSizeYUm ;
189175 }
190176
191- // Origin of the grid in stage space: top-left corner adjusted for centering offset.
192- final double originX = minX - offsetXUm ;
193- final double originY = minY - offsetYUm ;
177+ // Anchor the grid at the center of the bounding box and place tiles
178+ // symmetrically around it. Sign-agnostic: affine step vectors may contain
179+ // reflections/rotation (negative components), but building outward from the
180+ // center keeps the grid centered on the user's region while still applying
181+ // the rotation through the step vectors.
182+ final double centerX = (minX + maxX ) / 2.0 ;
183+ final double centerY = (minY + maxY ) / 2.0 ;
194184
195185 PositionList posList = new PositionList ();
196186 for (int y = 0 ; y < nrImagesY ; y ++) {
@@ -205,8 +195,10 @@ public PositionList createTiles(double overlap, OverlapUnitEnum overlapUnit,
205195 // Add XY position
206196 // xyStage is not null; we've checked above.
207197 msp .setDefaultXYStage (xyStage );
208- double dx = originX + tmpX * stepXdx + y * stepYdx ;
209- double dy = originY + tmpX * stepXdy + y * stepYdy ;
198+ double offX = tmpX - (nrImagesX - 1 ) / 2.0 ;
199+ double offY = y - (nrImagesY - 1 ) / 2.0 ;
200+ double dx = centerX + offX * stepXdx + offY * stepYdx ;
201+ double dy = centerY + offX * stepXdy + offY * stepYdy ;
210202 StagePosition spXY = StagePosition .create2D (xyStage , dx , dy );
211203 msp .add (spXY );
212204
0 commit comments