made roads more dense near city centers
This commit is contained in:
@@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user