stopped point of interest on water
This commit is contained in:
@@ -125,26 +125,6 @@ func main() {
|
|||||||
|
|
||||||
var roadImage *image.RGBA
|
var roadImage *image.RGBA
|
||||||
|
|
||||||
roadPixels, roadImage = GenerateRoads(settings.Width, settings.Height, settings, noiseImg)
|
|
||||||
|
|
||||||
// Draw roadImage over finalImage
|
|
||||||
|
|
||||||
for y := 0; y < roadImage.Bounds().Max.Y; y++ {
|
|
||||||
|
|
||||||
for x := 0; x < roadImage.Bounds().Max.X; x++ {
|
|
||||||
|
|
||||||
r, g, b, a := roadImage.At(x, y).RGBA()
|
|
||||||
|
|
||||||
if a > 0 {
|
|
||||||
|
|
||||||
finalImage.Set(x, y, color.RGBA{R: uint8(r >> 8), G: uint8(g >> 8), B: uint8(b >> 8), A: uint8(a >> 8)})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
var flatLakePixels []image.Point
|
var flatLakePixels []image.Point
|
||||||
|
|
||||||
for _, lake := range lakes {
|
for _, lake := range lakes {
|
||||||
@@ -154,6 +134,15 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
allWaterPixels := append(flatLakePixels, riverPixels...)
|
allWaterPixels := append(flatLakePixels, riverPixels...)
|
||||||
|
roadPixels, roadImage = GenerateRoads(settings.Width, settings.Height, settings, noiseImg, allWaterPixels)
|
||||||
|
for y := 0; y < roadImage.Bounds().Max.Y; y++ {
|
||||||
|
for x := 0; x < roadImage.Bounds().Max.X; x++ {
|
||||||
|
r, g, b, a := roadImage.At(x, y).RGBA()
|
||||||
|
if a > 0 {
|
||||||
|
finalImage.Set(x, y, color.RGBA{R: uint8(r >> 8), G: uint8(g >> 8), B: uint8(b >> 8), A: uint8(a >> 8)})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
treePixels = GenerateTrees(finalImage, allWaterPixels, settings.MinTreeSize, settings.MaxTreeSize, settings.TreeCoverage, settings.TreeClumpiness, settings.Seed)
|
treePixels = GenerateTrees(finalImage, allWaterPixels, settings.MinTreeSize, settings.MaxTreeSize, settings.TreeCoverage, settings.TreeClumpiness, settings.Seed)
|
||||||
|
|
||||||
@@ -299,7 +288,7 @@ func main() {
|
|||||||
treeClumpinessSlider.SetValue(settings.TreeClumpiness)
|
treeClumpinessSlider.SetValue(settings.TreeClumpiness)
|
||||||
|
|
||||||
numRoadsLabel := widget.NewLabel(fmt.Sprintf("Number of Roads: %d", settings.NumRoads))
|
numRoadsLabel := widget.NewLabel(fmt.Sprintf("Number of Roads: %d", settings.NumRoads))
|
||||||
numRoadsSlider := widget.NewSlider(1, 1000)
|
numRoadsSlider := widget.NewSlider(0, 1000)
|
||||||
numRoadsSlider.OnChanged = func(val float64) {
|
numRoadsSlider.OnChanged = func(val float64) {
|
||||||
settings.NumRoads = int(val)
|
settings.NumRoads = int(val)
|
||||||
numRoadsLabel.SetText(fmt.Sprintf("Number of Roads: %d", settings.NumRoads))
|
numRoadsLabel.SetText(fmt.Sprintf("Number of Roads: %d", settings.NumRoads))
|
||||||
@@ -332,7 +321,7 @@ func main() {
|
|||||||
maxRoadWidthSlider.SetValue(settings.MaxRoadWidth)
|
maxRoadWidthSlider.SetValue(settings.MaxRoadWidth)
|
||||||
|
|
||||||
roadExitsLabel := widget.NewLabel(fmt.Sprintf("Road Exits: %d", settings.RoadExits))
|
roadExitsLabel := widget.NewLabel(fmt.Sprintf("Road Exits: %d", settings.RoadExits))
|
||||||
roadExitsSlider := widget.NewSlider(1, 100)
|
roadExitsSlider := widget.NewSlider(0, 100)
|
||||||
roadExitsSlider.OnChanged = func(val float64) {
|
roadExitsSlider.OnChanged = func(val float64) {
|
||||||
if val > float64(settings.NumRoads) {
|
if val > float64(settings.NumRoads) {
|
||||||
val = float64(settings.NumRoads)
|
val = float64(settings.NumRoads)
|
||||||
@@ -417,6 +406,12 @@ func main() {
|
|||||||
|
|
||||||
finalImage := riverImage.(*image.RGBA)
|
finalImage := riverImage.(*image.RGBA)
|
||||||
|
|
||||||
|
var flatLakePixels []image.Point
|
||||||
|
for _, lake := range lakes {
|
||||||
|
flatLakePixels = append(flatLakePixels, lake...)
|
||||||
|
}
|
||||||
|
allWaterPixels := append(flatLakePixels, riverPixels...)
|
||||||
|
|
||||||
// Step 4: Generating Roads
|
// Step 4: Generating Roads
|
||||||
currentStep++
|
currentStep++
|
||||||
fyne.Do(func() {
|
fyne.Do(func() {
|
||||||
@@ -424,7 +419,7 @@ func main() {
|
|||||||
progressBar.SetValue(float64(currentStep) / float64(steps))
|
progressBar.SetValue(float64(currentStep) / float64(steps))
|
||||||
})
|
})
|
||||||
var roadImage *image.RGBA
|
var roadImage *image.RGBA
|
||||||
roadPixels, roadImage = GenerateRoads(settings.Width, settings.Height, settings, noiseImg) // Draw roadImage over finalImage
|
roadPixels, roadImage = GenerateRoads(settings.Width, settings.Height, settings, noiseImg, allWaterPixels) // Draw roadImage over finalImage
|
||||||
for y := 0; y < roadImage.Bounds().Max.Y; y++ {
|
for y := 0; y < roadImage.Bounds().Max.Y; y++ {
|
||||||
for x := 0; x < roadImage.Bounds().Max.X; x++ {
|
for x := 0; x < roadImage.Bounds().Max.X; x++ {
|
||||||
r, g, b, a := roadImage.At(x, y).RGBA()
|
r, g, b, a := roadImage.At(x, y).RGBA()
|
||||||
@@ -434,12 +429,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var flatLakePixels []image.Point
|
|
||||||
for _, lake := range lakes {
|
|
||||||
flatLakePixels = append(flatLakePixels, lake...)
|
|
||||||
}
|
|
||||||
allWaterPixels := append(flatLakePixels, riverPixels...)
|
|
||||||
|
|
||||||
// Step 5: Darkening Water Areas
|
// Step 5: Darkening Water Areas
|
||||||
currentStep++
|
currentStep++
|
||||||
fyne.Do(func() {
|
fyne.Do(func() {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ type Road struct {
|
|||||||
Importance int
|
Importance int
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenerateRoads(width, height int, settings *Settings, noiseImg image.Image) ([]image.Point, *image.RGBA) {
|
func GenerateRoads(width, height int, settings *Settings, noiseImg image.Image, allWaterPixels []image.Point) ([]image.Point, *image.RGBA) {
|
||||||
img := image.NewRGBA(image.Rect(0, 0, width, height))
|
img := image.NewRGBA(image.Rect(0, 0, width, height))
|
||||||
// Transparent background
|
// Transparent background
|
||||||
for y := 0; y < height; y++ {
|
for y := 0; y < height; y++ {
|
||||||
@@ -34,7 +34,7 @@ func GenerateRoads(width, height int, settings *Settings, noiseImg image.Image)
|
|||||||
rand.Seed(settings.Seed)
|
rand.Seed(settings.Seed)
|
||||||
roadColor := color.RGBA{R: 139, G: 69, B: 19, A: 255}
|
roadColor := color.RGBA{R: 139, G: 69, B: 19, A: 255}
|
||||||
|
|
||||||
pois := generatePOIs(width, height, settings)
|
pois := generatePOIs(width, height, settings, allWaterPixels)
|
||||||
if len(pois) == 0 {
|
if len(pois) == 0 {
|
||||||
return nil, img
|
return nil, img
|
||||||
}
|
}
|
||||||
@@ -51,18 +51,23 @@ func GenerateRoads(width, height int, settings *Settings, noiseImg image.Image)
|
|||||||
return allRoadPixels, img
|
return allRoadPixels, img
|
||||||
}
|
}
|
||||||
|
|
||||||
func generatePOIs(width, height int, settings *Settings) []*PointOfInterest {
|
func generatePOIs(width, height int, settings *Settings, allWaterPixels []image.Point) []*PointOfInterest {
|
||||||
numPOIs := settings.NumRoads / 2
|
numPOIs := settings.NumRoads / 2
|
||||||
if numPOIs == 0 {
|
if numPOIs == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
waterMap := make(map[image.Point]bool)
|
||||||
|
for _, p := range allWaterPixels {
|
||||||
|
waterMap[p] = true
|
||||||
|
}
|
||||||
|
|
||||||
numExits := settings.RoadExits
|
numExits := settings.RoadExits
|
||||||
if numExits > settings.NumRoads {
|
if numExits > settings.NumRoads {
|
||||||
numExits = settings.NumRoads
|
numExits = settings.NumRoads
|
||||||
}
|
}
|
||||||
|
|
||||||
pois := make([]*PointOfInterest, numPOIs)
|
pois := make([]*PointOfInterest, 0, numPOIs)
|
||||||
centerX := width / 2
|
centerX := width / 2
|
||||||
centerY := height / 2
|
centerY := height / 2
|
||||||
|
|
||||||
@@ -71,10 +76,11 @@ func generatePOIs(width, height int, settings *Settings) []*PointOfInterest {
|
|||||||
radius := maxRadius * (settings.RoadDistribution / 100.0)
|
radius := maxRadius * (settings.RoadDistribution / 100.0)
|
||||||
|
|
||||||
for i := 0; i < numPOIs; i++ {
|
for i := 0; i < numPOIs; i++ {
|
||||||
// Handle exits
|
var x, y int
|
||||||
|
found := false
|
||||||
|
for j := 0; j < 100; j++ { // 100 retries to find a land spot
|
||||||
if i < numExits {
|
if i < numExits {
|
||||||
side := rand.Intn(4)
|
side := rand.Intn(4)
|
||||||
var x, y int
|
|
||||||
switch side {
|
switch side {
|
||||||
case 0: // Top
|
case 0: // Top
|
||||||
x = rand.Intn(width)
|
x = rand.Intn(width)
|
||||||
@@ -89,15 +95,21 @@ func generatePOIs(width, height int, settings *Settings) []*PointOfInterest {
|
|||||||
x = width - 1
|
x = width - 1
|
||||||
y = rand.Intn(height)
|
y = rand.Intn(height)
|
||||||
}
|
}
|
||||||
pois[i] = &PointOfInterest{X: x, Y: y}
|
} else {
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
angle := rand.Float64() * 2 * math.Pi
|
angle := rand.Float64() * 2 * math.Pi
|
||||||
r := rand.Float64() * radius
|
r := rand.Float64() * radius
|
||||||
x := int(float64(centerX) + r*math.Cos(angle))
|
x = int(float64(centerX) + r*math.Cos(angle))
|
||||||
y := int(float64(centerY) + r*math.Sin(angle))
|
y = int(float64(centerY) + r*math.Sin(angle))
|
||||||
pois[i] = &PointOfInterest{X: x, Y: y}
|
}
|
||||||
|
|
||||||
|
if !waterMap[image.Point{X: x, Y: y}] {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if found {
|
||||||
|
pois = append(pois, &PointOfInterest{X: x, Y: y})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return pois
|
return pois
|
||||||
@@ -119,6 +131,9 @@ func connectPOIs(pois []*PointOfInterest, width, height int, settings *Settings)
|
|||||||
minDist := -1.0
|
minDist := -1.0
|
||||||
|
|
||||||
for _, poi := range pois {
|
for _, poi := range pois {
|
||||||
|
if poi == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
dist := math.Sqrt(math.Pow(float64(poi.X-centerX), 2) + math.Pow(float64(poi.Y-centerY), 2))
|
dist := math.Sqrt(math.Pow(float64(poi.X-centerX), 2) + math.Pow(float64(poi.Y-centerY), 2))
|
||||||
if startNode == nil || dist < minDist {
|
if startNode == nil || dist < minDist {
|
||||||
minDist = dist
|
minDist = dist
|
||||||
@@ -126,6 +141,10 @@ func connectPOIs(pois []*PointOfInterest, width, height int, settings *Settings)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if startNode == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
visited[startNode] = true
|
visited[startNode] = true
|
||||||
|
|
||||||
for len(visited) < len(pois) {
|
for len(visited) < len(pois) {
|
||||||
@@ -135,6 +154,9 @@ func connectPOIs(pois []*PointOfInterest, width, height int, settings *Settings)
|
|||||||
|
|
||||||
for poi := range visited {
|
for poi := range visited {
|
||||||
for _, other := range pois {
|
for _, other := range pois {
|
||||||
|
if poi == nil || other == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
if !visited[other] {
|
if !visited[other] {
|
||||||
dist := math.Sqrt(math.Pow(float64(poi.X-other.X), 2) + math.Pow(float64(poi.Y-other.Y), 2))
|
dist := math.Sqrt(math.Pow(float64(poi.X-other.X), 2) + math.Pow(float64(poi.Y-other.Y), 2))
|
||||||
|
|
||||||
@@ -182,6 +204,9 @@ func connectPOIs(pois []*PointOfInterest, width, height int, settings *Settings)
|
|||||||
End: closest,
|
End: closest,
|
||||||
Control: &PointOfInterest{X: controlX, Y: controlY},
|
Control: &PointOfInterest{X: controlX, Y: controlY},
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
// No more reachable POIs
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user