made roads more dense near city centers

This commit is contained in:
grimsace
2026-04-06 10:10:21 -05:00
parent 4888e10f73
commit ac9f012015
+26 -12
View File
@@ -368,11 +368,17 @@ func generatePOIs(width, height int, settings *Settings, waterMask *PixelMask, r
break break
} }
p := image.Point{X: x, Y: y} p := image.Point{X: x, Y: y}
centerDist := math.Hypot(float64(x-centerX), float64(y-centerY))
centerFactor := 1.0 - clamp01(centerDist/(effectiveRadius+1))
localSpacing := avgBuildingSize * (1.36 - 0.68*centerFactor)
if localSpacing < 4 {
localSpacing = 4
}
// Keep larger spacing between intersections so buildings have room. // Keep larger spacing between intersections so buildings have room.
if waterMask.GetPoint(p) || isTooCloseToExisting(pois, x, y, avgBuildingSize*1.1) { if waterMask.GetPoint(p) || isTooCloseToExisting(pois, x, y, localSpacing) {
continue continue
} }
pois = append(pois, &PointOfInterest{X: x, Y: y, TargetDegree: sampleTargetDegree(randSrc)}) pois = append(pois, &PointOfInterest{X: x, Y: y, TargetDegree: sampleTargetDegree(randSrc, centerFactor)})
} }
if len(pois) == 0 { if len(pois) == 0 {
@@ -383,7 +389,7 @@ func generatePOIs(width, height int, settings *Settings, waterMask *PixelMask, r
centerDist := math.Hypot(float64(poi.X-centerX), float64(poi.Y-centerY)) centerDist := math.Hypot(float64(poi.X-centerX), float64(poi.Y-centerY))
centerFactor := 1.0 - clamp01(centerDist/(effectiveRadius+1)) centerFactor := 1.0 - clamp01(centerDist/(effectiveRadius+1))
sizeFactor := clamp01((avgBuildingSize - 4.0) / 40.0) sizeFactor := clamp01((avgBuildingSize - 4.0) / 40.0)
poi.ArterialWeight = clamp01(0.60*centerFactor + 0.40*sizeFactor) poi.ArterialWeight = clamp01(0.72*centerFactor + 0.28*sizeFactor)
} }
return pois return pois
@@ -395,7 +401,7 @@ func estimateCoreNodeCount(width, height int, distribution, avgBuildingSize floa
if spacing < 6 { if spacing < 6 {
spacing = 6 spacing = 6
} }
byArea := int((targetArea / (spacing * spacing)) * 0.18) byArea := int((targetArea / (spacing * spacing)) * 0.20)
buildingPressure := int(math.Sqrt(float64(max(numBuildings, 1))) * (0.7 + distribution*0.9)) buildingPressure := int(math.Sqrt(float64(max(numBuildings, 1))) * (0.7 + distribution*0.9))
nodes := byArea + buildingPressure nodes := byArea + buildingPressure
if nodes < 8 { if nodes < 8 {
@@ -475,19 +481,22 @@ func sampleEdgePOI(width, height int, randSrc *rand.Rand) *PointOfInterest {
} }
} }
func sampleTargetDegree(randSrc *rand.Rand) int { func sampleTargetDegree(randSrc *rand.Rand, centerFactor float64) int {
centerFactor = clamp01(centerFactor)
r := randSrc.Float64() r := randSrc.Float64()
switch { switch {
case r < 0.03: case r < 0.04-0.02*centerFactor:
return 1 return 1
case r < 0.17: case r < 0.18-0.06*centerFactor:
return 2 return 2
case r < 0.40: case r < 0.42-0.06*centerFactor:
return 3 return 3
case r < 0.85: case r < 0.86-0.20*centerFactor:
return 4 return 4
default: case r < 0.97-0.08*(1.0-centerFactor):
return 5 return 5
default:
return 6
} }
} }
@@ -683,7 +692,8 @@ func connectPOIs(pois []*PointOfInterest, width, height int, settings *Settings,
b := pois[c.b] b := pois[c.b]
centerPenalty := centerCloseness(a) * centerCloseness(b) * 0.45 centerPenalty := centerCloseness(a) * centerCloseness(b) * 0.45
degreePenalty := clamp01(float64(a.Connections+b.Connections) / 8.0) degreePenalty := clamp01(float64(a.Connections+b.Connections) / 8.0)
score := c.arterialMean*0.58 + clamp01(c.dist/edgeDist)*0.27 + c.score*0.15 - centerPenalty - degreePenalty*0.18 coreBonus := (centerCloseness(a) + centerCloseness(b)) * 0.22
score := c.arterialMean*0.58 + clamp01(c.dist/edgeDist)*0.27 + c.score*0.15 + coreBonus - centerPenalty - degreePenalty*0.18
if score > bestScore { if score > bestScore {
bestScore = score bestScore = score
bestIdx = idx bestIdx = idx
@@ -733,7 +743,8 @@ func connectPOIs(pois []*PointOfInterest, width, height int, settings *Settings,
if !a.IsExit && !b.IsExit { if !a.IsExit && !b.IsExit {
longDiagonalPenalty = clamp01((c.dist-edgeDist*0.45)/(edgeDist*0.35)) * 0.28 longDiagonalPenalty = clamp01((c.dist-edgeDist*0.45)/(edgeDist*0.35)) * 0.28
} }
score := c.score*0.28 + c.arterialMean*0.27 + distScore*0.35 + connectedBonus - centerPenalty - degreePenalty*0.14 - longDiagonalPenalty coreBonus := (centerCloseness(a) + centerCloseness(b)) * 0.18
score := c.score*0.28 + c.arterialMean*0.27 + distScore*0.35 + connectedBonus + coreBonus - centerPenalty - degreePenalty*0.14 - longDiagonalPenalty
if score > bestScore { if score > bestScore {
bestScore = score bestScore = score
bestIdx = idx bestIdx = idx
@@ -776,6 +787,9 @@ func connectPOIs(pois []*PointOfInterest, width, height int, settings *Settings,
if !a.IsExit && !b.IsExit && pick.dist > edgeDist*0.42 { if !a.IsExit && !b.IsExit && pick.dist > edgeDist*0.42 {
continue continue
} }
if centerCloseness(a)+centerCloseness(b) < 0.35 && randSrc.Float64() < 0.55 {
continue
}
addEdge(pick, RoadTierLocal) addEdge(pick, RoadTierLocal)
} }