added mixed building generation
This commit is contained in:
+31
-1
@@ -118,7 +118,11 @@ func GenerateBuildings(img *image.RGBA, width, height int, settings *Settings, r
|
||||
|
||||
// Attempt to create a building at the selected center
|
||||
size := settings.MinBuildingSize + randSrc.Float64()*(settings.MaxBuildingSize-settings.MinBuildingSize)
|
||||
pixels, ok := getBuildingPixels(center, size, settings.BuildingShape, isWater, isRoad, isBuilding, width, height, randSrc)
|
||||
shape := settings.BuildingShape
|
||||
if shape == "mixed" {
|
||||
shape = chooseShape(randSrc, settings.BuildingShapeRatios)
|
||||
}
|
||||
pixels, ok := getBuildingPixels(center, size, shape, isWater, isRoad, isBuilding, width, height, randSrc)
|
||||
if ok {
|
||||
// If successful, draw the building and update data structures
|
||||
for _, p := range pixels {
|
||||
@@ -134,6 +138,32 @@ func GenerateBuildings(img *image.RGBA, width, height int, settings *Settings, r
|
||||
return buildingPixels
|
||||
}
|
||||
|
||||
// chooseShape selects a building shape based on the provided ratios.
|
||||
func chooseShape(randSrc *rand.Rand, ratios map[string]float64) string {
|
||||
// Create a slice of shapes and their cumulative weights
|
||||
var shapes []string
|
||||
var weights []float64
|
||||
var cumulativeWeight float64
|
||||
for shape, weight := range ratios {
|
||||
shapes = append(shapes, shape)
|
||||
cumulativeWeight += weight
|
||||
weights = append(weights, cumulativeWeight)
|
||||
}
|
||||
|
||||
// Generate a random number between 0 and the total weight
|
||||
randNum := randSrc.Float64() * cumulativeWeight
|
||||
|
||||
// Find the shape corresponding to the random number
|
||||
for i, weight := range weights {
|
||||
if randNum < weight {
|
||||
return shapes[i]
|
||||
}
|
||||
}
|
||||
|
||||
// Default to the first shape if something goes wrong
|
||||
return shapes[0]
|
||||
}
|
||||
|
||||
// getBuildingPixels determines the pixels for a single building based on its shape and checks for collisions.
|
||||
func getBuildingPixels(center image.Point, size float64, shape string, isWater, isRoad, isBuilding map[image.Point]bool, width, height int, randSrc *rand.Rand) ([]image.Point, bool) {
|
||||
var pixels []image.Point
|
||||
|
||||
@@ -650,11 +650,147 @@ func main() {
|
||||
buildingDistributionSlider.SetValue(settings.BuildingDistribution)
|
||||
|
||||
buildingShapeLabel := widget.NewLabel("Building Shape:")
|
||||
buildingShapeSelect := widget.NewSelect([]string{"squares", "circles", "rectangles"}, func(s string) {
|
||||
buildingShapeSelect := widget.NewSelect([]string{"squares", "circles", "rectangles", "mixed"}, func(s string) {
|
||||
settings.BuildingShape = s
|
||||
})
|
||||
buildingShapeSelect.SetSelected(settings.BuildingShape)
|
||||
|
||||
// Create sliders for building shape ratios (visible only when "mixed" is selected)
|
||||
squareRatioSlider := widget.NewSlider(0, 100)
|
||||
circleRatioSlider := widget.NewSlider(0, 100)
|
||||
rectangleRatioSlider := widget.NewSlider(0, 100)
|
||||
|
||||
squareRatioLabel := widget.NewLabel(fmt.Sprintf("Squares: %.0f%%", settings.BuildingShapeRatios["squares"]))
|
||||
circleRatioLabel := widget.NewLabel(fmt.Sprintf("Circles: %.0f%%", settings.BuildingShapeRatios["circles"]))
|
||||
rectangleRatioLabel := widget.NewLabel(fmt.Sprintf("Rectangles: %.0f%%", settings.BuildingShapeRatios["rectangles"]))
|
||||
|
||||
squareRatioSlider.SetValue(settings.BuildingShapeRatios["squares"])
|
||||
circleRatioSlider.SetValue(settings.BuildingShapeRatios["circles"])
|
||||
rectangleRatioSlider.SetValue(settings.BuildingShapeRatios["rectangles"])
|
||||
|
||||
ratioContainer := container.NewVBox(
|
||||
squareRatioLabel,
|
||||
squareRatioSlider,
|
||||
circleRatioLabel,
|
||||
circleRatioSlider,
|
||||
rectangleRatioLabel,
|
||||
rectangleRatioSlider,
|
||||
)
|
||||
|
||||
updateRatioSliders := func() {
|
||||
squareRatioSlider.SetValue(settings.BuildingShapeRatios["squares"])
|
||||
circleRatioSlider.SetValue(settings.BuildingShapeRatios["circles"])
|
||||
rectangleRatioSlider.SetValue(settings.BuildingShapeRatios["rectangles"])
|
||||
squareRatioLabel.SetText(fmt.Sprintf("Squares: %.0f%%", settings.BuildingShapeRatios["squares"]))
|
||||
circleRatioLabel.SetText(fmt.Sprintf("Circles: %.0f%%", settings.BuildingShapeRatios["circles"]))
|
||||
rectangleRatioLabel.SetText(fmt.Sprintf("Rectangles: %.0f%%", settings.BuildingShapeRatios["rectangles"]))
|
||||
}
|
||||
|
||||
squareRatioSlider.OnChanged = func(val float64) {
|
||||
if settings.BuildingShape != "mixed" {
|
||||
return
|
||||
}
|
||||
oldVal := settings.BuildingShapeRatios["squares"]
|
||||
diff := val - oldVal
|
||||
settings.BuildingShapeRatios["squares"] = val
|
||||
settings.BuildingShapeRatios["circles"] -= diff / 2
|
||||
settings.BuildingShapeRatios["rectangles"] -= diff / 2
|
||||
|
||||
// Clamp values to 0-100 range
|
||||
if settings.BuildingShapeRatios["circles"] < 0 {
|
||||
settings.BuildingShapeRatios["rectangles"] += settings.BuildingShapeRatios["circles"]
|
||||
settings.BuildingShapeRatios["circles"] = 0
|
||||
}
|
||||
if settings.BuildingShapeRatios["rectangles"] < 0 {
|
||||
settings.BuildingShapeRatios["circles"] += settings.BuildingShapeRatios["rectangles"]
|
||||
settings.BuildingShapeRatios["rectangles"] = 0
|
||||
}
|
||||
if settings.BuildingShapeRatios["circles"] > 100 {
|
||||
settings.BuildingShapeRatios["rectangles"] += settings.BuildingShapeRatios["circles"] - 100
|
||||
settings.BuildingShapeRatios["circles"] = 100
|
||||
}
|
||||
if settings.BuildingShapeRatios["rectangles"] > 100 {
|
||||
settings.BuildingShapeRatios["circles"] += settings.BuildingShapeRatios["rectangles"] - 100
|
||||
settings.BuildingShapeRatios["rectangles"] = 100
|
||||
}
|
||||
|
||||
updateRatioSliders()
|
||||
}
|
||||
|
||||
circleRatioSlider.OnChanged = func(val float64) {
|
||||
if settings.BuildingShape != "mixed" {
|
||||
return
|
||||
}
|
||||
oldVal := settings.BuildingShapeRatios["circles"]
|
||||
diff := val - oldVal
|
||||
settings.BuildingShapeRatios["circles"] = val
|
||||
settings.BuildingShapeRatios["squares"] -= diff / 2
|
||||
settings.BuildingShapeRatios["rectangles"] -= diff / 2
|
||||
// Clamp values to 0-100 range
|
||||
if settings.BuildingShapeRatios["squares"] < 0 {
|
||||
settings.BuildingShapeRatios["rectangles"] += settings.BuildingShapeRatios["squares"]
|
||||
settings.BuildingShapeRatios["squares"] = 0
|
||||
}
|
||||
if settings.BuildingShapeRatios["rectangles"] < 0 {
|
||||
settings.BuildingShapeRatios["squares"] += settings.BuildingShapeRatios["rectangles"]
|
||||
settings.BuildingShapeRatios["rectangles"] = 0
|
||||
}
|
||||
if settings.BuildingShapeRatios["squares"] > 100 {
|
||||
settings.BuildingShapeRatios["rectangles"] += settings.BuildingShapeRatios["squares"] - 100
|
||||
settings.BuildingShapeRatios["squares"] = 100
|
||||
}
|
||||
if settings.BuildingShapeRatios["rectangles"] > 100 {
|
||||
settings.BuildingShapeRatios["squares"] += settings.BuildingShapeRatios["rectangles"] - 100
|
||||
settings.BuildingShapeRatios["rectangles"] = 100
|
||||
}
|
||||
|
||||
updateRatioSliders()
|
||||
}
|
||||
|
||||
rectangleRatioSlider.OnChanged = func(val float64) {
|
||||
if settings.BuildingShape != "mixed" {
|
||||
return
|
||||
}
|
||||
oldVal := settings.BuildingShapeRatios["rectangles"]
|
||||
diff := val - oldVal
|
||||
settings.BuildingShapeRatios["rectangles"] = val
|
||||
settings.BuildingShapeRatios["squares"] -= diff / 2
|
||||
settings.BuildingShapeRatios["circles"] -= diff / 2
|
||||
|
||||
// Clamp values to 0-100 range
|
||||
if settings.BuildingShapeRatios["squares"] < 0 {
|
||||
settings.BuildingShapeRatios["circles"] += settings.BuildingShapeRatios["squares"]
|
||||
settings.BuildingShapeRatios["squares"] = 0
|
||||
}
|
||||
if settings.BuildingShapeRatios["circles"] < 0 {
|
||||
settings.BuildingShapeRatios["squares"] += settings.BuildingShapeRatios["circles"]
|
||||
settings.BuildingShapeRatios["circles"] = 0
|
||||
}
|
||||
if settings.BuildingShapeRatios["squares"] > 100 {
|
||||
settings.BuildingShapeRatios["circles"] += settings.BuildingShapeRatios["squares"] - 100
|
||||
settings.BuildingShapeRatios["squares"] = 100
|
||||
}
|
||||
if settings.BuildingShapeRatios["circles"] > 100 {
|
||||
settings.BuildingShapeRatios["squares"] += settings.BuildingShapeRatios["circles"] - 100
|
||||
settings.BuildingShapeRatios["circles"] = 100
|
||||
}
|
||||
|
||||
updateRatioSliders()
|
||||
}
|
||||
|
||||
buildingShapeSelect.OnChanged = func(s string) {
|
||||
settings.BuildingShape = s
|
||||
if s == "mixed" {
|
||||
ratioContainer.Show()
|
||||
} else {
|
||||
ratioContainer.Hide()
|
||||
}
|
||||
}
|
||||
// Initial visibility check
|
||||
if settings.BuildingShape != "mixed" {
|
||||
ratioContainer.Hide()
|
||||
}
|
||||
|
||||
buildingsTab := container.NewTabItem("Buildings", container.NewVBox(
|
||||
numBuildingsLabel,
|
||||
numBuildingsSlider,
|
||||
@@ -666,6 +802,7 @@ func main() {
|
||||
buildingDistributionSlider,
|
||||
buildingShapeLabel,
|
||||
buildingShapeSelect,
|
||||
ratioContainer,
|
||||
))
|
||||
|
||||
imageTab := container.NewTabItem("Image", container.NewVBox(
|
||||
|
||||
+18
-1
@@ -45,6 +45,9 @@ type Settings struct {
|
||||
BuildingDistribution float64 `json:"building_distribution"`
|
||||
BuildingShape string `json:"building_shape"`
|
||||
|
||||
// Ratios for mixed building shapes
|
||||
BuildingShapeRatios map[string]float64 `json:"building_shape_ratios"`
|
||||
|
||||
// General settings
|
||||
Seed int64 `json:"seed"`
|
||||
LastExportPath string `json:"last_export_path"`
|
||||
@@ -123,7 +126,12 @@ func LoadSettings() (*Settings, error) {
|
||||
MinBuildingSize: 10,
|
||||
MaxBuildingSize: 30,
|
||||
BuildingDistribution: 20,
|
||||
BuildingShape: "squares",
|
||||
BuildingShape: "mixed",
|
||||
BuildingShapeRatios: map[string]float64{
|
||||
"squares": 40,
|
||||
"circles": 30,
|
||||
"rectangles": 30,
|
||||
},
|
||||
LastExportPath: homeDir,
|
||||
}, nil
|
||||
}
|
||||
@@ -138,6 +146,15 @@ func LoadSettings() (*Settings, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Ensure BuildingShapeRatios is initialized
|
||||
if settings.BuildingShapeRatios == nil {
|
||||
settings.BuildingShapeRatios = map[string]float64{
|
||||
"squares": 40,
|
||||
"circles": 30,
|
||||
"rectangles": 30,
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure LastExportPath is set to a default value if it's empty
|
||||
if settings.LastExportPath == "" {
|
||||
homeDir, err := os.UserHomeDir()
|
||||
|
||||
Reference in New Issue
Block a user