changed lake roughness to make it more simliar to rivers

This commit is contained in:
Grimsace
2026-02-18 15:14:47 -06:00
parent 6227ecb3fd
commit 710c05f716
3 changed files with 32 additions and 9 deletions
+16 -2
View File
@@ -153,7 +153,7 @@ func main() {
// Step 2: Generating Lakes // Step 2: Generating Lakes
var lakeImage image.Image var lakeImage image.Image
lakeImage, lakes = GenerateLakes(settings.Width, settings.Height, settings.Lakes, settings.LakeSizeLower, settings.LakeSizeUpper, noiseImg, seedProvider.Next()) lakeImage, lakes = GenerateLakes(settings.Width, settings.Height, settings.Lakes, settings.LakeSizeLower, settings.LakeSizeUpper, seedProvider.Next(), settings.LakeEdgeRoughness)
// Step 3: Generating Rivers // Step 3: Generating Rivers
var riverImage image.Image var riverImage image.Image
@@ -291,6 +291,19 @@ func main() {
val, _ := lakeSizeUpperSlider.value.Get() val, _ := lakeSizeUpperSlider.value.Get()
settings.LakeSizeUpper = val settings.LakeSizeUpper = val
})) }))
lakeEdgeRoughnessSlider := newNumericInputSlider(0, 100, settings.LakeEdgeRoughness, "%.0f%%", "Lake Edge Roughness")
lakeEdgeRoughnessSlider.entry.OnChanged = func(s string) {
lakeEdgeRoughnessSlider.validate(s, func(hasError bool) {
errorStates["lakeEdgeRoughness"] = hasError
updateGenerateBtnState()
})
}
lakeEdgeRoughnessSlider.value.AddListener(binding.NewDataListener(func() {
val, _ := lakeEdgeRoughnessSlider.value.Get()
settings.LakeEdgeRoughness = val
}))
riversSlider := newNumericInputSlider(0, 5, float64(settings.Rivers), "%.0f", "Rivers") riversSlider := newNumericInputSlider(0, 5, float64(settings.Rivers), "%.0f", "Rivers")
riversSlider.entry.OnChanged = func(s string) { riversSlider.entry.OnChanged = func(s string) {
riversSlider.validate(s, func(hasError bool) { riversSlider.validate(s, func(hasError bool) {
@@ -532,7 +545,7 @@ func main() {
progressBar.SetValue(2.0 / 11.0) progressBar.SetValue(2.0 / 11.0)
}) })
var lakeImage image.Image var lakeImage image.Image
lakeImage, lakes = GenerateLakes(settings.Width, settings.Height, settings.Lakes, settings.LakeSizeLower, settings.LakeSizeUpper, noiseImg, seedProvider.Next()) lakeImage, lakes = GenerateLakes(settings.Width, settings.Height, settings.Lakes, settings.LakeSizeLower, settings.LakeSizeUpper, seedProvider.Next(), settings.LakeEdgeRoughness)
// Step 3: Generating Rivers // Step 3: Generating Rivers
@@ -700,6 +713,7 @@ func main() {
lakesSlider, lakesSlider,
lakeSizeLowerSlider, lakeSizeLowerSlider,
lakeSizeUpperSlider, lakeSizeUpperSlider,
lakeEdgeRoughnessSlider,
widget.NewLabel(""), // Spacer widget.NewLabel(""), // Spacer
+2
View File
@@ -19,6 +19,7 @@ type Settings struct {
Lakes int `json:"lakes"` Lakes int `json:"lakes"`
LakeSizeLower float64 `json:"lake_size_lower"` LakeSizeLower float64 `json:"lake_size_lower"`
LakeSizeUpper float64 `json:"lake_size_upper"` LakeSizeUpper float64 `json:"lake_size_upper"`
LakeEdgeRoughness float64 `json:"lake_edge_roughness"`
Rivers int `json:"rivers"` Rivers int `json:"rivers"`
MinRiverWidth float64 `json:"min_river_width"` MinRiverWidth float64 `json:"min_river_width"`
MaxRiverWidth float64 `json:"max_river_width"` MaxRiverWidth float64 `json:"max_river_width"`
@@ -115,6 +116,7 @@ func LoadSettings() (*Settings, error) {
Lakes: 0, Lakes: 0,
LakeSizeLower: 1, LakeSizeLower: 1,
LakeSizeUpper: 5, LakeSizeUpper: 5,
LakeEdgeRoughness: 50,
MinTreeSize: 5, MinTreeSize: 5,
MaxTreeSize: 20, MaxTreeSize: 20,
TreeCoverage: 20, TreeCoverage: 20,
+14 -7
View File
@@ -47,7 +47,8 @@ func (pq *priorityQueue) Pop() any {
} }
// GenerateLakes creates lakes on the map using a growth algorithm. // GenerateLakes creates lakes on the map using a growth algorithm.
func GenerateLakes(width, height, numLakes int, lakeSizeLower, lakeSizeUpper float64, heightmap image.Image, seed int64) (image.Image, [][]image.Point) { // When lakeEdgeRoughness is 0, lakes grow in perfect circles. Higher values add noise-based irregularity.
func GenerateLakes(width, height, numLakes int, lakeSizeLower, lakeSizeUpper float64, seed int64, lakeEdgeRoughness float64) (image.Image, [][]image.Point) {
// Initialize a white canvas to draw the lakes on // Initialize a white canvas to draw the lakes on
canvas := image.NewRGBA(image.Rect(0, 0, width, height)) canvas := image.NewRGBA(image.Rect(0, 0, width, height))
draw.Draw(canvas, canvas.Bounds(), image.NewUniform(color.White), image.Point{}, draw.Src) draw.Draw(canvas, canvas.Bounds(), image.NewUniform(color.White), image.Point{}, draw.Src)
@@ -125,7 +126,7 @@ func GenerateLakes(width, height, numLakes int, lakeSizeLower, lakeSizeUpper flo
continue continue
} }
// Use noise to create a more natural lake shape. // Use noise to create a more natural lake shape (only if roughness > 0).
seedX := randSrc.Float64() * 10000.0 seedX := randSrc.Float64() * 10000.0
seedY := randSrc.Float64() * 10000.0 seedY := randSrc.Float64() * 10000.0
radius := math.Sqrt(float64(targetPixelsPerLake) / math.Pi) radius := math.Sqrt(float64(targetPixelsPerLake) / math.Pi)
@@ -134,12 +135,18 @@ func GenerateLakes(width, height, numLakes int, lakeSizeLower, lakeSizeUpper flo
getScore := func(pt image.Point) float64 { getScore := func(pt image.Point) float64 {
dx, dy := pt.X-startPt.X, pt.Y-startPt.Y dx, dy := pt.X-startPt.X, pt.Y-startPt.Y
dist := math.Sqrt(float64(dx*dx + dy*dy)) dist := math.Sqrt(float64(dx*dx + dy*dy))
noise := noiseGen.Eval2(seedX+float64(dx)*noiseFreq, seedY+float64(dy)*noiseFreq)
distPenalty := math.Pow(dist/radius, 3.0) distPenalty := math.Pow(dist/radius, 3.0)
luma, _, _, _ := heightmap.At(pt.X, pt.Y).RGBA()
heightmapVal := float64(luma) / 65535.0 // Only apply noise if edge roughness is requested
heightmapEffect := (0.5 - heightmapVal) * 1.5 // Encourage growth in lower areas if lakeEdgeRoughness > 0 {
return noise - distPenalty + heightmapEffect noise := noiseGen.Eval2(seedX+float64(dx)*noiseFreq, seedY+float64(dy)*noiseFreq)
// Scale noise contribution by roughness setting
noiseContribution := noise * (lakeEdgeRoughness / 100.0)
return noiseContribution - distPenalty
}
// Pure circular growth when variability is 0
return -distPenalty
} }
heap.Push(pq, &lakePixel{point: startPt, score: getScore(startPt)}) heap.Push(pq, &lakePixel{point: startPt, score: getScore(startPt)})