func makeSpriteFromFragments(frags []fragment) (s Sprite) {
	if len(frags) == 0 {
		return
	}
	p := make([]point, 0, len(frags))
	for i := range frags {
		x := int32(math32.Round(frags[i].sx))
		y := int32(math32.Round(frags[i].sy))
		if -128 <= x && x < 128 && -128 <= y && y < 128 {
			p = append(p, point{int8(x), int8(y)})
		}
	}
	sort.Sort(byYX(p))
	// Now build s
	var j int
	for i := 0; i < len(p); i = j {
		y := p[i].y
		for j = i + 1; j < len(p) && p[j].y == y; j++ {
		}
		x := make([]int8, j-i)
		for k := range x {
			x[k] = p[i+k].x
		}
		s.rows = append(s.rows, spriteRow{y, x})
	}
	return
}
// drawFrequonsFourier draws the frequency-domain representation of Frequons.
func drawFrequonsFourier(pm nimble.PixMap) {
	c := universe.Zoo
	h := harmonicStorage[:len(c)]

	var ampScale float32
	if autoGain.Value {
		// Compute L1 norm of amplitudes
		norm := float32(0)
		for i := range c {
			norm += math32.Abs(c[i].Amplitude)
		}
		ampScale = 1 / norm
	} else {
		ampScale = 1 / float32(len(c))
	}
	fracX, fracY := universe.BoxFraction()
	fracX *= zoomCompression
	fracY *= zoomCompression
	sizeX, sizeY := pm.Size()

	// Set up harmonics
	// (cx,cy) is center of fourier view
	cx, cy := 0.5*float32(sizeX)*fracX, 0.5*float32(sizeY)*fracY
	α, β := -0.5*cx, -0.5*cy
	ωScale := 200. / float32(sizeX*sizeY)
	for i := range h {
		ωx := (c[i].Sx - cx) * ωScale
		ωy := (c[i].Sy - cy) * ωScale
		h[i].Ωx = ωx
		h[i].Ωy = ωy
		h[i].Phase = α*ωx + β*ωy + phaseRoll
		// Scale amplitude so that DFT values fit within domain of color lookup table.
		h[i].Amplitude = c[i].Amplitude * ampScale
	}

	marginX := int32(math32.Round(0.5 * float32(sizeX) * (1 - fracX)))
	marginY := int32(math32.Round(0.5 * float32(sizeY) * (1 - fracY)))
	fourier.Draw(pm.Intersect(nimble.Rect{
		Left:   marginX,
		Right:  sizeX - marginX,
		Top:    marginY,
		Bottom: sizeY - marginY,
	}), h, universe.Scheme())
	if marginX != 0 || marginY != 0 {
		pm.DrawRect(nimble.Rect{Left: 0, Right: sizeX, Top: 0, Bottom: marginY}, nimble.Black)
		pm.DrawRect(nimble.Rect{Left: 0, Right: sizeX, Top: sizeY - marginY, Bottom: sizeY}, nimble.Black)
		pm.DrawRect(nimble.Rect{Left: 0, Right: marginX, Top: marginY, Bottom: sizeY - marginY}, nimble.Black)
		pm.DrawRect(nimble.Rect{Left: sizeX - marginX, Right: sizeX, Top: marginY, Bottom: sizeY - marginY}, nimble.Black)
	}
}
// drawFrequonsSpatial draws the spatial-domain representation of Frequons.
// (xf,yf) is the location of the player.
func drawFrequonsSpatial(pm nimble.PixMap, xf, yf int32) {
	nPastel := pastels.Width()
	for k := 1; k < len(universe.Zoo); k++ {
		c := &universe.Zoo[k]
		d := int32(math32.Hypot(float32(xf)-c.Sx, float32(yf)-c.Sy))
		if c.Show || d < nPastel {
			i := c.ImageIndex()
			if i < len(critterSeq[k]) {
				j := int32(0)
				if !c.Show {
					j = d
				}
				sprite.Draw(pm, int32(math32.Round(c.Sx)), int32(math32.Round(c.Sy)), critterSeq[k][i], pastels.Pixel(j, int32(c.Id)))
			}
		}
	}
	if fourierPort.Contains(mouseX, mouseY) {
		sprite.Draw(pm, xf, yf, critterSeq[0][0], nimble.White)
	}
}
Exemple #4
0
func (context) Init(width, height int32) {
	if width < 640 || height < 400 {
		panic(fmt.Sprintf("screen size of %v x %v is too small!", width, height))
	}
	screenWidth, screenHeight = width, height
	nShade := int32(math32.Round(math32.Sqrt(float32(width*height)) * (32. / 1440)))
	initCritterSprites(width, height)
	pastels = coloring.PastelPalette(universe.MaxCritter, nShade)
	teletype.Init("Characters.png")
	if benchmarking {
		bootSequencePeriod = 0
		setMode(modeTraining)
	} else {
		setMode(modeSplash) // N.B. also causes partitionScreen to be called
		if devConfig {
			teletype.Print("[debug mode]\n")
		}
	}
}