Skip to content

Instantly share code, notes, and snippets.

@zhaostu
Created January 28, 2017 19:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zhaostu/e472b4ba8867a61fd4b8c1db692bdde7 to your computer and use it in GitHub Desktop.
Save zhaostu/e472b4ba8867a61fd4b8c1db692bdde7 to your computer and use it in GitHub Desktop.
package main
import (
"image"
"image/color"
"image/draw"
"image/png"
"log"
"math"
"os"
)
type NumberSpiral struct {
NIntegers int
Resolution float64 // Pixel per unit
image draw.Image
nonprimes []bool
}
func (ns *NumberSpiral) prepare() {
// Calculate image bounds and initialize image
max := int(math.Ceil(math.Sqrt(float64(ns.NIntegers)) * ns.Resolution))
rect := image.Rect(
-max, -max, max, max,
)
ns.image = image.NewGray(rect)
// Sieve primes
ns.nonprimes = make([]bool, ns.NIntegers)
ns.nonprimes[0] = true
ns.nonprimes[1] = true
sr := int(math.Sqrt(float64(ns.NIntegers)))
for i := 2; i <= sr; i++ {
if ns.nonprimes[i] {
continue
}
for n := i * 2; n < ns.NIntegers; n += i {
ns.nonprimes[n] = true
}
}
}
func (ns *NumberSpiral) Draw() {
ns.prepare()
// Fill with white color
draw.Draw(ns.image, ns.image.Bounds(), image.White, image.ZP, draw.Src)
// Draw numbers.
for i := 0; i < ns.NIntegers; i++ {
r := math.Sqrt(float64(i))
theta := r * 2 * math.Pi
x := int(r * math.Cos(theta) * ns.Resolution)
y := int(-r * math.Sin(theta) * ns.Resolution)
var c color.Color
if ns.nonprimes[i] {
c = color.Gray{192}
} else {
c = color.Black
}
ns.image.Set(x, y, c)
}
}
func (ns *NumberSpiral) Image() image.Image {
return ns.image
}
func main() {
ns := NumberSpiral{NIntegers: 1000, Resolution: 5.0}
ns.Draw()
f, err := os.Create("output.png")
if err != nil {
log.Fatal("Could not open output file.")
}
png.Encode(f, ns.Image())
f.Close()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment