// RandomMirror builds an image with 10x10 grids of half diagonals func RandomMirror(w http.ResponseWriter, colors []color.RGBA, size int, prob float64) { canvas := svg.New(w) canvas.Start(size, size) lines := 10 fringeSize := size / lines distance := distanceTo3rdPoint(fringeSize) fringeSize = distance lines = size / fringeSize for xL := 0; xL <= lines/2; xL++ { for yL := -1; yL < lines; yL++ { var x1, x2, y1, y2, y3 int if (xL % 2) == 0 { x1, y1, x2, y2, _, y3 = right1stTriangle(xL, yL, fringeSize, distance) } else { x1, y1, x2, y2, _, y3 = left1stTriangle(xL, yL, fringeSize, distance) } xs := []int{x2, x1, x2} ys := []int{y1, y2, y3} fill1 := draw.FillFromRGBA(draw.RandomColorFromArrayWithFreq(colors, prob)) canvas.Polygon(xs, ys, fill1) xs = mirrorCoordinates(xs, lines, fringeSize, 0) canvas.Polygon(xs, ys, fill1) var x11, x12, y11, y12, y13 int if (xL % 2) == 0 { x11, y11, x12, y12, _, y13 = left2ndTriangle(xL, yL, fringeSize, distance) // we make sure that the previous triangle and this one touch each other in this point. y12 = y3 } else { x11, y11, x12, y12, _, y13 = right2ndTriangle(xL, yL, fringeSize, distance) // in order to have a perfect hexagon, // we make sure that the previous triangle and this one touch each other in this point. y12 = y1 + fringeSize } xs1 := []int{x12, x11, x12} ys1 := []int{y11, y12, y13} fill2 := draw.FillFromRGBA(draw.RandomColorFromArrayWithFreq(colors, prob)) canvas.Polygon(xs1, ys1, fill2) xs1 = mirrorCoordinates(xs1, lines, fringeSize, 0) canvas.Polygon(xs1, ys1, fill2) } } canvas.End() }
// Isogrids builds an image with 10x10 grids of half diagonals func Isogrids(w http.ResponseWriter, key string, colors []color.RGBA, size, lines int) { canvas := svg.New(w) canvas.Start(size, size) fringeSize := size / lines distance := distanceTo3rdPoint(fringeSize) lines = size / fringeSize offset := ((fringeSize - distance) * lines) / 2 // triangle grid here: for xL := -1; xL < lines/2; xL++ { for yL := -1; yL <= lines; yL++ { var x1, x2, y1, y2, y3 int if (xL % 2) == 0 { x1, y1, x2, y2, _, y3 = right1stTriangle(xL, yL, fringeSize, distance) } else { x1, y1, x2, y2, _, y3 = left1stTriangle(xL, yL, fringeSize, distance) } xs := []int{x2 + offset, x1 + offset, x2 + offset} ys := []int{y1, y2, y3} fill1 := draw.FillFromRGBA(draw.PickColor(key, colors, (xL+3*yL+lines)%15)) canvas.Polygon(xs, ys, fill1) xsMirror := mirrorCoordinates(xs, lines, distance, offset*2) canvas.Polygon(xsMirror, ys, fill1) var x11, x12, y11, y12, y13 int if (xL % 2) == 0 { x11, y11, x12, y12, _, y13 = left2ndTriangle(xL, yL, fringeSize, distance) // we make sure that the previous triangle and this one touch each other in this point. y12 = y3 } else { x11, y11, x12, y12, _, y13 = right2ndTriangle(xL, yL, fringeSize, distance) // in order to have a perfect hexagon, // we make sure that the previous triangle and this one touch each other in this point. y12 = y1 + fringeSize } xs1 := []int{x12 + offset, x11 + offset, x12 + offset} ys1 := []int{y11, y12, y13} fill2 := draw.FillFromRGBA(draw.PickColor(key, colors, (xL+3*yL+1+lines)%15)) canvas.Polygon(xs1, ys1, fill2) xs1 = mirrorCoordinates(xs1, lines, distance, offset*2) canvas.Polygon(xs1, ys1, fill2) } } canvas.End() }
// SVG builds an svg image with 6 by 6 quadrants of alternate colors. func SVG(w http.ResponseWriter, key string, colors []color.RGBA, size int) { canvas := svg.New(w) canvas.Start(size, size) squares := 6 quadrantSize := size / squares middle := math.Ceil(float64(squares) / float64(2)) colorMap := make(map[int]color.RGBA) for yQ := 0; yQ < squares; yQ++ { y := yQ * quadrantSize colorMap = make(map[int]color.RGBA) for xQ := 0; xQ < squares; xQ++ { x := xQ * quadrantSize if _, ok := colorMap[xQ]; !ok { if float64(xQ) < middle { colorMap[xQ] = draw.PickColor(key, colors, xQ+3*yQ) } else if xQ < squares { colorMap[xQ] = colorMap[squares-xQ-1] } else { colorMap[xQ] = colorMap[0] } } canvas.Rect(x, y, quadrantSize, quadrantSize, draw.FillFromRGBA(colorMap[xQ])) } } canvas.End() }
// triangleColors returns an array of strings, one for each sub triangle. // Each string corresponds to an svg color. // Colors are selected from the array of colors passed as parameter and the key. func triangleColors(id int, key string, colors []color.RGBA, lines int) (tColors []string) { for _, t := range triangles[id] { x := t.x y := t.y tColors = append(tColors, draw.FillFromRGBA(draw.PickColor(key, colors, (x+3*y+lines)%15))) } return }
// RandomGradient creates an isogrids svg image with half diagonals. // colors are filled at random in the image with a frequency that decreases // from left to right. func RandomGradient(w http.ResponseWriter, colors []color.RGBA, width, height, lines int) { canvas := svg.New(w) canvas.Start(width, height) fringeSize := width / lines distance := distanceTo3rdPoint(fringeSize) fringeSize = distance lines = width / fringeSize for xL := 0; xL < lines; xL++ { percentage := 100 - int(float64(xL)/float64(lines)*100) for yL := -1; yL < lines; yL++ { var x1, x2, y1, y2, y3 int if (xL % 2) == 0 { x1, y1, x2, y2, _, y3 = right1stTriangle(xL, yL, fringeSize, distance) } else { x1, y1, x2, y2, _, y3 = left1stTriangle(xL, yL, fringeSize, distance) } xs := []int{x2, x1, x2} ys := []int{y1, y2, y3} canvas.Polygon(xs, ys, draw.FillFromRGBA(draw.ColorByPercentage(colors, percentage))) var x11, x12, y11, y12, y13 int if (xL % 2) == 0 { x11, y11, x12, y12, _, y13 = left2ndTriangle(xL, yL, fringeSize, distance) // we make sure that the previous triangle and this one touch each other in this point. y12 = y3 } else { x11, y11, x12, y12, _, y13 = right2ndTriangle(xL, yL, fringeSize, distance) // in order to have a perfect hexagon, // we make sure that the previous triangle and this one touch each other in this point. y12 = y1 + fringeSize } xs1 := []int{x12, x11, x12} ys1 := []int{y11, y12, y13} canvas.Polygon(xs1, ys1, draw.FillFromRGBA(draw.ColorByPercentage(colors, percentage))) } } canvas.End() }
// Random builds an image with 10x10 grids of half diagonals with random background. // The image is symetric in the middle vertical axis. func Random(w http.ResponseWriter, colors []color.RGBA, width, height, lines int, prob float64) { canvas := svg.New(w) canvas.Start(width, height) fringeSize := width / lines distance := distanceTo3rdPoint(fringeSize) fringeSize = distance lines = width / fringeSize for xL := 0; xL < lines; xL++ { for yL := -1; yL <= lines; yL++ { var x1, x2, y1, y2, y3 int if (xL % 2) == 0 { x1, y1, x2, y2, _, y3 = right1stTriangle(xL, yL, fringeSize, distance) } else { x1, y1, x2, y2, _, y3 = left1stTriangle(xL, yL, fringeSize, distance) } xs := []int{x2, x1, x2} ys := []int{y1, y2, y3} canvas.Polygon(xs, ys, draw.FillFromRGBA(draw.RandomColorFromArrayWithFreq(colors, prob))) var x11, x12, y11, y12, y13 int if (xL % 2) == 0 { x11, y11, x12, y12, _, y13 = left2ndTriangle(xL, yL, fringeSize, distance) // we make sure that the previous triangle and this one touch each other in this point. y12 = y3 } else { x11, y11, x12, y12, _, y13 = right2ndTriangle(xL, yL, fringeSize, distance) // we make sure that the previous triangle and this one touch each other in this point. y12 = y1 + fringeSize } xs1 := []int{x12, x11, x12} ys1 := []int{y11, y12, y13} canvas.Polygon(xs1, ys1, draw.FillFromRGBA(draw.RandomColorFromArrayWithFreq(colors, prob))) } } canvas.End() }
// PaletteSVG builds an SVG image with all the colors present in the theme color array. func PaletteSVG(w http.ResponseWriter, theme []color.RGBA, width, height int) { canvas := svg.New(w) canvas.Start(width, height) numColors := len(theme) quadrant := width / numColors for xQ := 0; xQ < numColors; xQ++ { x := xQ * quadrant currentQuadrant := (x / quadrant) % numColors canvas.Rect(x, 0, quadrant, height, draw.FillFromRGBA(theme[currentQuadrant])) } canvas.End() }
// RandomGradientColorSVG builds a square image with with x colors selected at random for each quadrant. // the background color stays the same the other colors get mixed in a gradient color from the first one to the last one. func RandomGradientColorSVG(w http.ResponseWriter, colors, gColors []color.RGBA, gv colors.GradientVector, width, height, xsquares int, prob float64) { var gradientColors []svg.Offcolor gradientColors = make([]svg.Offcolor, len(gColors)) percentage := uint8(0) step := uint8(100 / len(gColors)) for i, c := range gColors { gradientColors[i] = svg.Offcolor{ Offset: percentage, Color: draw.RGBToHex(c.R, c.G, c.B), Opacity: 1, } percentage += step } canvas := svg.New(w) canvas.Start(width, height) canvas.Def() canvas.LinearGradient("gradientColors", gv.X1, gv.Y1, gv.X2, gv.Y2, gradientColors) canvas.DefEnd() canvas.Rect(0, 0, width, height, "fill:url(#gradientColors)") squares := xsquares quadrantSize := width / squares colorMap := make(map[int]color.RGBA) colorIndex := make(map[int]int) for yQ := 0; yQ < squares; yQ++ { y := yQ * quadrantSize colorMap = make(map[int]color.RGBA) colorIndex = make(map[int]int) for xQ := 0; xQ <= squares+1; xQ++ { x := xQ * quadrantSize if _, ok := colorMap[xQ]; !ok { colorIndex[xQ] = draw.RandomIndexFromArrayWithFreq(colors, prob) colorMap[xQ] = colors[colorIndex[xQ]] } if colorIndex[xQ] == 0 { fill := draw.FillFromRGBA(colorMap[xQ]) canvas.Rect(x, y, quadrantSize, quadrantSize, fill) } } } canvas.End() }
// RandomGridSVG builds a grid image with with x colors selected at random for each quadrant. func RandomGridSVG(w http.ResponseWriter, colors []color.RGBA, width, height, xSquares int, prob float64) { canvas := svg.New(w) canvas.Start(width, height) squares := xSquares quadrantSize := width / squares colorMap := make(map[int]color.RGBA) for yQ := 0; yQ < squares; yQ++ { y := yQ * quadrantSize colorMap = make(map[int]color.RGBA) for xQ := 0; xQ < squares; xQ++ { x := xQ * quadrantSize if _, ok := colorMap[xQ]; !ok { colorMap[xQ] = draw.RandomColorFromArrayWithFreq(colors, prob) } canvas.Rect(x, y, quadrantSize, quadrantSize, draw.FillFromRGBA(colorMap[xQ])) } } canvas.End() }
// RandomGradientGridSVG builds a grid image with with x colors selected at random for each quadrant. func RandomGradientGridSVG(w http.ResponseWriter, colors []color.RGBA, width, height, xSquares int) { canvas := svg.New(w) canvas.Start(width, height) squares := xSquares quadrantSize := width / squares colorMap := make(map[int]color.RGBA) for yQ := 0; yQ < squares; yQ++ { y := yQ * quadrantSize colorMap = make(map[int]color.RGBA) for xQ := 0; xQ < squares; xQ++ { x := xQ * quadrantSize if _, ok := colorMap[xQ]; !ok { percentage := 100 - int(float64(xQ)/float64(squares)*100) colorMap[xQ] = draw.ColorByPercentage(colors, percentage) } canvas.Rect(x, y, quadrantSize, quadrantSize, draw.FillFromRGBA(colorMap[xQ])) } } canvas.End() }
// GridSVG builds an image with 6 by 6 quadrants of alternate colors. func GridSVG(w http.ResponseWriter, color1, color2 color.RGBA, size int) { canvas := svg.New(w) canvas.Start(size, size) squares := 6 quadrantSize := size / squares colorMap := make(map[int]color.RGBA) for yQ := 0; yQ < squares; yQ++ { y := yQ * quadrantSize colorMap = make(map[int]color.RGBA) for xQ := 0; xQ < squares; xQ++ { x := xQ * quadrantSize if _, ok := colorMap[xQ]; !ok { if (xQ+yQ)%2 == 0 { colorMap[xQ] = color1 } else { colorMap[xQ] = color2 } } canvas.Rect(x, y, quadrantSize, quadrantSize, draw.FillFromRGBA(colorMap[xQ])) } } canvas.End() }
// SpaceInvaders builds a space invader svg image based on the 'key' and // 'colors' passed as arguments. The svg image is written to the http.ResponseWriter passed as // argument. func SpaceInvaders(w http.ResponseWriter, key string, colors []color.RGBA, size int) { canvas := svg.New(w) canvas.Start(size, size) invader := newInvader(key) // log.Println(fmt.Sprintf("%+v\n", invader)) // for debug squares := 11 quadrantSize := size / squares middle := math.Ceil(float64(squares) / float64(2)) colorMap := make(map[int]color.RGBA) // style of space invader background canvas.Gstyle(draw.FillFromRGBA(colors[0])) for yQ := 0; yQ < squares; yQ++ { y := yQ * quadrantSize colorMap = make(map[int]color.RGBA) for xQ := 0; xQ < squares; xQ++ { x := xQ * quadrantSize fill := "" if _, ok := colorMap[xQ]; !ok { colorMap[xQ] = selectColor(colorMap, key, colors, middle, xQ, yQ, squares) } highBodyIndex := 2 if hasEyeOrAnthena(invader, &highBodyIndex, squares, xQ, yQ) { fill = draw.FillFromRGBA(colorMap[xQ]) } if hasArmOrExtension(invader, squares, xQ, yQ) { fill = draw.FillFromRGBA(colorMap[xQ]) } if yQ == 5 { // clean eye from arm extension if eye, c := hasEye4(invader, colorMap, colors, xQ); eye { fill = draw.FillFromRGBA(c) } } if yQ == 6 { if hasBody(invader, squares, xQ) { fill = draw.FillFromRGBA(colorMap[xQ]) } } lowBodyIndex := 7 if hasBody2(invader, &lowBodyIndex, squares, xQ, yQ) { fill = draw.FillFromRGBA(colorMap[xQ]) } if hasArmOrExtension2(invader, lowBodyIndex, squares, xQ, yQ) { fill = draw.FillFromRGBA(colorMap[xQ]) } if hasLegOrFoot(invader, lowBodyIndex, xQ, yQ) { fill = draw.FillFromRGBA(colorMap[xQ]) } if len(fill) > 0 { canvas.Rect(x, y, quadrantSize, quadrantSize, fill) } else { canvas.Rect(x, y, quadrantSize, quadrantSize) } } } canvas.Gend() canvas.End() }
// RandomGradientColor builds a isogrid image with with x colors selected at random for each quadrant. // the background color stays the same the other colors get mixed in a gradient color from the first one to the last one. func RandomGradientColor(w http.ResponseWriter, colors, gColors []color.RGBA, gv colors.GradientVector, width, height, lines int, prob float64) { var gradientColors []svg.Offcolor gradientColors = make([]svg.Offcolor, len(gColors)) percentage := uint8(0) step := uint8(100 / len(gColors)) for i, c := range gColors { gradientColors[i] = svg.Offcolor{ Offset: percentage, Color: draw.RGBToHex(c.R, c.G, c.B), Opacity: 1, } percentage += step } canvas := svg.New(w) canvas.Start(width, height) canvas.Def() canvas.LinearGradient("gradientColors", gv.X1, gv.Y1, gv.X2, gv.Y2, gradientColors) canvas.DefEnd() canvas.Rect(0, 0, width, height, "fill:url(#gradientColors)") fringeSize := width / lines distance := distanceTo3rdPoint(fringeSize) fringeSize = distance lines = width / fringeSize colorMap := make(map[int]color.RGBA) colorIndex := make(map[int]int) for xL := 0; xL <= lines; xL++ { colorMap = make(map[int]color.RGBA) colorIndex = make(map[int]int) for yL := -1; yL <= lines; yL++ { var x1, x2, y1, y2, y3 int if (xL % 2) == 0 { x1, y1, x2, y2, _, y3 = right1stTriangle(xL, yL, fringeSize, distance) } else { x1, y1, x2, y2, _, y3 = left1stTriangle(xL, yL, fringeSize, distance) } xs := []int{x2, x1, x2} ys := []int{y1, y2, y3} colorIndex[yL] = draw.RandomIndexFromArrayWithFreq(colors, prob) colorMap[yL] = colors[colorIndex[yL]] if colorIndex[yL] == 0 { canvas.Polygon(xs, ys, draw.FillFromRGBA(colorMap[yL])) } var x11, x12, y11, y12, y13 int if (xL % 2) == 0 { x11, y11, x12, y12, _, y13 = left2ndTriangle(xL, yL, fringeSize, distance) // we make sure that the previous triangle and this one touch each other in this point. y12 = y3 } else { x11, y11, x12, y12, _, y13 = right2ndTriangle(xL, yL, fringeSize, distance) // we make sure that the previous triangle and this one touch each other in this point. y12 = y1 + fringeSize } xs1 := []int{x12, x11, x12} ys1 := []int{y11, y12, y13} colorIndex[yL] = draw.RandomIndexFromArrayWithFreq(colors, prob) colorMap[yL] = colors[colorIndex[yL]] if colorIndex[yL] == 0 { canvas.Polygon(xs1, ys1, draw.FillFromRGBA(colorMap[yL])) } } } canvas.End() }