From bfde9fa584e60135637f7764485c9276eefa5572 Mon Sep 17 00:00:00 2001 From: augustus Date: Wed, 24 Nov 2021 18:18:31 +0000 Subject: [PATCH] Include lava - volcanic areas now include regions of lava (well, they did anyways, but it's now extended) - add alpha tool to facilitate transparentifying things --- cmd/alpha/main.go | 101 +++++++++++++++++++++++++++++++++++++ pkg/landscape/area.go | 14 ++--- pkg/landscape/config.go | 4 ++ pkg/landscape/geography.go | 12 +++-- pkg/landscape/land.go | 3 +- 5 files changed, 124 insertions(+), 10 deletions(-) create mode 100644 cmd/alpha/main.go diff --git a/cmd/alpha/main.go b/cmd/alpha/main.go new file mode 100644 index 0000000..377554c --- /dev/null +++ b/cmd/alpha/main.go @@ -0,0 +1,101 @@ +package main + +import ( + "bytes" + "fmt" + "image" + "image/color" + _ "image/gif" + _ "image/jpeg" + "image/png" + "io/ioutil" + "os" + + "github.com/alecthomas/kong" +) + +const desc = `Alpha tool takes some input image & a region (x0,y0)->(x1,y1). + +All colours in the given region are made fully transparent across the image. +` + +var cli struct { + // + Input string `arg short:"i" type:"existingfile" help:"input image"` + + AlphaX0 int `arg long:"alpha-x0" help:"x0 of region designating colours to alpha"` + AlphaY0 int `arg long:"alpha-y0" help:"y0 of region designating colours to alpha"` + AlphaX1 int `arg long:"alpha-x1" help:"x1 of region designating colours to alpha"` + AlphaY1 int `arg long:"alpha-y1" help:"y1 of region designating colours to alpha"` + + // + Output string `short:"o" default:"out.png" help:"output name"` +} + +func main() { + kong.Parse( + &cli, + kong.Name("alpha"), + kong.Description(desc), + ) + fmt.Println("args", cli) + + f, err := os.Open(cli.Input) + if err != nil { + panic(err) + } + + im, _, err := image.Decode(f) + if err != nil { + panic(err) + } + + toalpha := coloursInRegion(im, cli.AlphaX0, cli.AlphaY0, cli.AlphaX1, cli.AlphaY1) + fmt.Printf("colors to remove: %d\n", len(toalpha)) + if len(toalpha) < 1 { + panic(fmt.Errorf("region must contain at least one colour")) + } + + bnds := im.Bounds() + out := image.NewRGBA(bnds) + + for dy := bnds.Min.Y; dy < bnds.Max.Y; dy++ { + for dx := bnds.Min.X; dx < bnds.Max.X; dx++ { + c := im.At(dx, dy) + _, ok := toalpha[c] + if ok { + out.Set(dx, dy, color.RGBA{255, 255, 255, 0}) + } else { + out.Set(dx, dy, c) + } + } + } + + err = savePng(cli.Output, out) + if err != nil { + panic(err) + } +} + +// coloursInRegion returns a map of colours found in the given region +func coloursInRegion(im image.Image, x0, y0, x1, y1 int) map[color.Color]bool { + cs := map[color.Color]bool{} + + for dy := y0; dy <= y1; dy++ { + for dx := x0; dx <= x1; dx++ { + cs[im.At(dx, dy)] = true + } + } + + return cs +} + +// savePng to disk +func savePng(fpath string, in image.Image) error { + buff := new(bytes.Buffer) + err := png.Encode(buff, in) + if err != nil { + return err + } + return ioutil.WriteFile(fpath, buff.Bytes(), 0644) +} diff --git a/pkg/landscape/area.go b/pkg/landscape/area.go index 9728a7e..7d836ab 100644 --- a/pkg/landscape/area.go +++ b/pkg/landscape/area.go @@ -8,12 +8,14 @@ type Area struct { Temperature uint8 // in degress c, offset so 100 => 0 degrees cel Volcanism uint8 - // if the square contains fresh/salt water - Sea bool - River bool - Lake bool // lake implies river - Swamp bool // swamp water - Swampland bool // water ridden land + // if the square contains fresh/salt water/lava + Sea bool + River bool + Lake bool // lake implies river + Swamp bool // swamp water + Lava bool + + BiomeSwamp bool // if river, we set a river ID else 0 RiverID int diff --git a/pkg/landscape/config.go b/pkg/landscape/config.go index 96a9fb2..986f00f 100644 --- a/pkg/landscape/config.go +++ b/pkg/landscape/config.go @@ -27,6 +27,9 @@ type volcSettings struct { // min dist volcanoes must have from each other OriginMinDist float64 + + // at or over this value we consider volanic land lava + LavaOver uint8 } type swampSettings struct { @@ -115,6 +118,7 @@ func DefaultConfig() *Config { Radius: 30, Variance: 0.7, OriginMinDist: 10, + LavaOver: 180, }, Swamp: &swampSettings{ Number: 8, diff --git a/pkg/landscape/geography.go b/pkg/landscape/geography.go index dadb98a..cf5bebb 100644 --- a/pkg/landscape/geography.go +++ b/pkg/landscape/geography.go @@ -109,7 +109,8 @@ func determineGeothermal(hmap *MapImage, vs *volcSettings) (*MapImage, []*POI) { for _, volcano := range origins { pois = append(pois, &POI{X: volcano.X(), Y: volcano.Y(), Type: Volcano}) - vmap.SetValue(volcano.X(), volcano.Y(), 255) + + lavamap := &MapImage{im: perlin.Perlin(x, y, vs.Variance*1.5)} // describe square around origin for dy := volcano.Y() - int(vs.Radius)/2; dy < volcano.Y()+int(vs.Radius)/2; dy++ { @@ -117,6 +118,11 @@ func determineGeothermal(hmap *MapImage, vs *volcSettings) (*MapImage, []*POI) { current := vmap.Value(dx, dy) pv := pmap.Value(dx, dy) + if lavamap.Value(dx, dy) > vs.LavaOver { + pv = 255 + hmap.SetValue(dx, dy, decrement(hmap.Value(dx, dy), 5)) + } + dist := math.Sqrt( math.Pow(float64(volcano.X())-float64(dx), 2) + math.Pow(float64(volcano.Y())-float64(dy), 2), ) @@ -126,9 +132,9 @@ func determineGeothermal(hmap *MapImage, vs *volcSettings) (*MapImage, []*POI) { continue } else if dist > vs.Radius/2 { pv /= 6 - } else if dist > vs.Radius/3 { + } else if dist > vs.Radius/3 && pv != 255 { pv /= 4 - } else if dist > vs.Radius/4 { + } else if dist > vs.Radius/4 && pv != 255 { pv /= 2 } diff --git a/pkg/landscape/land.go b/pkg/landscape/land.go index 0a31828..4884746 100644 --- a/pkg/landscape/land.go +++ b/pkg/landscape/land.go @@ -72,8 +72,9 @@ func (l *Landscape) At(x, y int) *Area { River: l.rivers.Value(x, y) == 255, Temperature: l.temperature.Value(x, y), Swamp: l.swamp.Value(x, y) == 255, - Swampland: l.swamp.Value(x, y) == 120, + BiomeSwamp: l.swamp.Value(x, y) != 0, Volcanism: l.volcanic.Value(x, y), + Lava: l.volcanic.Value(x, y) == 255, } if !a.River { return a