fix: eliminate rail jaggies on sharp curves by increasing sampling density

The rails were rendered as polylines with points sampled at each tie position
(every 12 pixels). On sharp turns, the inside rail (smaller radius) didn't
have enough points to maintain smoothness, creating visible jaggies.

Solution: Separate tie generation from rail point generation. Ties still use
12px spacing (looks good), but rails now sample at 3px intervals (4x denser).
This provides enough points for smooth curves even on the inside rail of
sharp turns, while keeping tie density reasonable.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Thomas Hallock
2025-10-01 11:39:26 -05:00
parent 6c90a68c49
commit 46d4af2bda

View File

@@ -125,6 +125,7 @@ export class RailroadTrackGenerator {
const leftRailPoints: string[] = []
const rightRailPoints: string[] = []
// Generate ties at normal spacing
for (let i = 0; i < tieCount; i++) {
const distance = i * tieSpacing
const point = pathElement.getPointAtLength(distance)
@@ -143,6 +144,28 @@ export class RailroadTrackGenerator {
// Store tie
ties.push({ x1: leftX, y1: leftY, x2: rightX, y2: rightY })
}
// Generate rail points with much higher density for smooth curves
// Use 3px spacing instead of 12px tie spacing to eliminate jaggies on curves
const railSpacing = 3
const railPointCount = Math.floor(pathLength / railSpacing)
for (let i = 0; i < railPointCount; i++) {
const distance = i * railSpacing
const point = pathElement.getPointAtLength(distance)
// Calculate perpendicular angle for rail orientation
const nextDistance = Math.min(distance + 2, pathLength)
const nextPoint = pathElement.getPointAtLength(nextDistance)
const angle = Math.atan2(nextPoint.y - point.y, nextPoint.x - point.x)
const perpAngle = angle + Math.PI / 2
// Calculate rail positions
const leftX = point.x + Math.cos(perpAngle) * gaugeWidth
const leftY = point.y + Math.sin(perpAngle) * gaugeWidth
const rightX = point.x - Math.cos(perpAngle) * gaugeWidth
const rightY = point.y - Math.sin(perpAngle) * gaugeWidth
// Collect points for rails
leftRailPoints.push(`${leftX},${leftY}`)