💾 Archived View for thrig.me › blog › 2023 › 05 › 16 › circle.go captured on 2023-05-24 at 18:07:05.
-=-=-=-=-=-=-
// circle - draw circle like things package main import ( "fmt" "image" "image/color" "image/draw" "image/gif" "log" "math" "math/rand" "os" "time" ) type Circle struct { x int y int r int c uint8 h1 int // derived from y, radius, to find where circle is } var palette = []color.Color{ color.White, color.Black, color.NRGBA{255, 114, 114, 255}, color.NRGBA{255, 203, 114, 255}, color.NRGBA{255, 255, 114, 255}, color.NRGBA{57, 128, 57, 255}, color.NRGBA{114, 114, 255, 255}, color.NRGBA{99, 58, 130, 255}, color.NRGBA{238, 237, 238, 255}, color.NRGBA{78, 78, 78, 255}, color.NRGBA{99, 99, 99, 255}, color.NRGBA{130, 130, 130, 255}, color.NRGBA{156, 156, 156, 255}, color.NRGBA{208, 208, 208, 255}, color.NRGBA{237, 237, 237, 255}, color.NRGBA{239, 239, 239, 255}, /* color.NRGBA{239,239,239, 255}, color.NRGBA{237,237,237, 255}, color.NRGBA{208,208,208, 255}, color.NRGBA{156,156,156, 255}, color.NRGBA{130,130,130, 255}, color.NRGBA{99,99,99, 255}, color.NRGBA{78,78,78, 255}, */ /* //color.NRGBA{0, 105, 148, 255}, color.NRGBA{0x00, 0x8D, 0xC7, 255}, color.NRGBA{0x00, 0xB1, 0xFA, 255}, */ } const ( fg_color = 0 bg_color = 1 cidx1 = 2 cidx2 = 3 cidx3 = 4 cidx4 = 5 cidx5 = 6 cidx6 = 7 cidx7 = 8 //bg_color = 0 //fg_color = 1 //bl_color = 2 ) func cdhline(canvas *image.Paletted, c uint8, space, x1, x2, y int) { for x := x1; x <= x2; x += space { canvas.SetColorIndex(x, y, c) } } func chline(canvas *image.Paletted, c uint8, x1, x2, y int) { for x := x1; x <= x2; x++ { canvas.SetColorIndex(x, y, c) } } func chline2(canvas *image.Paletted, c uint8, x1, x2, y int) { x1 = x1 + irand(13) - 1 x2 = x2 + irand(21) - 7 for x := x1; x <= x2; x += 4 { canvas.SetColorIndex(x, y, c) } } func wcdhline(canvas *image.Paletted, c uint8, space, x1, x2, y int) { //x1 = x1 + irand(3) - 1 x2 = x2 + irand(7) - 3 for x := x1; x <= x2; x += space { canvas.SetColorIndex(x, y, c) canvas.SetColorIndex(x-1, y, c) canvas.SetColorIndex(x-1, y+1, c) canvas.SetColorIndex(x, y+1, c) canvas.SetColorIndex(x-1, y-1, c) canvas.SetColorIndex(x-2, y, c) canvas.SetColorIndex(x-2, y+2, c) canvas.SetColorIndex(x-1, y+2, c) canvas.SetColorIndex(x-2, y-2, c) canvas.SetColorIndex(x-4, y-1, c) canvas.SetColorIndex(x-3, y+3, c) canvas.SetColorIndex(x-2, y+3, c) } } func circle_fill(canvas *image.Paletted, circ *Circle, c uint8) { fmt.Fprintf(os.Stderr, "dbg y=%v r=%v %v\n", circ.y, circ.r, circ.y-circ.r) for y := 0; y <= circ.r; y++ { angle := math.Asin(float64(y) / float64(circ.r)) x := int(math.Cos(angle) * float64(circ.r)) start := circ.x - x end := circ.x + x chline(canvas, c, start, end, circ.y+y) chline(canvas, c, start, end, circ.y-y) } } func hline(canvas *image.Paletted, x1, x2, y int) { for x := x1; x <= x2; x++ { canvas.SetColorIndex(x, y, fg_color) } } func irand(max int) int { return int(rand.Int63n(int64(max))) } func main() { rand.Seed(time.Now().UTC().UnixNano()) with_gif("out.gif") fmt.Fprintf(os.Stderr, "ok\n") // KLUGE for "fmt" import } func make_circle(x, y, r int, c uint8) Circle { circ := Circle{ x: x, y: y, r: r, c: c, } circ.h1 = y - r // we really only need half the circle to find it //circ.h2 = y + r return circ } func rad2deg(radians float64) float64 { return radians * 180 / math.Pi } func with_gif(file string) { out, err := os.Create(file) if err != nil { log.Fatal(err) } defer out.Close() xsize := 320 ysize := 240 rect := image.Rect(0, 0, xsize, ysize) canvas := image.NewPaletted(rect, palette) draw.Draw(canvas, canvas.Bounds(), &image.Uniform{palette[bg_color]}, image.ZP, draw.Src) var circles []Circle circles = append(circles, make_circle(160, 120, 104, fg_color)) var cnum uint8 = cidx1 counter := -1 // with image-global horizontal lines of some spacing... for y := 0; y < ysize; y += 9 { for _, circ := range circles { if y >= circ.h1 && y <= circ.y { // half-circle intersects? opp := circ.y - y angle := math.Asin(float64(opp) / float64(circ.r)) adj := int(math.Cos(angle) * float64(circ.r)) start := circ.x - adj end := circ.x + adj cdhline(canvas, cnum, 3, start, end, circ.y-opp) // top half chline2(canvas, cnum+7, start, end, circ.y+opp + 3) counter++ if counter&1 == 1 { cnum++ if cnum > cidx7 { cnum = cidx1 } } } else { //cdhline(canvas, fg_color, 1, 0, xsize, y) } } } //cdhline(canvas, 4, 5, 0, xsize, 116) //dot := make_circle(130, 70, 16) //circle_fill(canvas, &dot, bg_color) options := &gif.Options{ NumColors: len(palette), } gif.Encode(out, canvas, options) }