91 lines
1.8 KiB
Go
91 lines
1.8 KiB
Go
|
package drawille
|
||
|
|
||
|
import (
|
||
|
"image"
|
||
|
)
|
||
|
|
||
|
const BRAILLE_OFFSET = '\u2800'
|
||
|
|
||
|
var BRAILLE = [4][2]rune{
|
||
|
{'\u0001', '\u0008'},
|
||
|
{'\u0002', '\u0010'},
|
||
|
{'\u0004', '\u0020'},
|
||
|
{'\u0040', '\u0080'},
|
||
|
}
|
||
|
|
||
|
type Color int
|
||
|
|
||
|
type Cell struct {
|
||
|
Rune rune
|
||
|
Color Color
|
||
|
}
|
||
|
|
||
|
type Canvas struct {
|
||
|
CellMap map[image.Point]Cell
|
||
|
}
|
||
|
|
||
|
func NewCanvas() *Canvas {
|
||
|
return &Canvas{
|
||
|
CellMap: make(map[image.Point]Cell),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (self *Canvas) SetPoint(p image.Point, color Color) {
|
||
|
point := image.Pt(p.X/2, p.Y/4)
|
||
|
self.CellMap[point] = Cell{
|
||
|
self.CellMap[point].Rune | BRAILLE[p.Y%4][p.X%2],
|
||
|
color,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (self *Canvas) SetLine(p0, p1 image.Point, color Color) {
|
||
|
for _, p := range line(p0, p1) {
|
||
|
self.SetPoint(p, color)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (self *Canvas) GetCells() map[image.Point]Cell {
|
||
|
cellMap := make(map[image.Point]Cell)
|
||
|
for point, cell := range self.CellMap {
|
||
|
cellMap[point] = Cell{cell.Rune + BRAILLE_OFFSET, cell.Color}
|
||
|
}
|
||
|
return cellMap
|
||
|
}
|
||
|
|
||
|
func line(p0, p1 image.Point) []image.Point {
|
||
|
points := []image.Point{}
|
||
|
|
||
|
leftPoint, rightPoint := p0, p1
|
||
|
if leftPoint.X > rightPoint.X {
|
||
|
leftPoint, rightPoint = rightPoint, leftPoint
|
||
|
}
|
||
|
|
||
|
xDistance := absInt(leftPoint.X - rightPoint.X)
|
||
|
yDistance := absInt(leftPoint.Y - rightPoint.Y)
|
||
|
slope := float64(yDistance) / float64(xDistance)
|
||
|
slopeSign := 1
|
||
|
if rightPoint.Y < leftPoint.Y {
|
||
|
slopeSign = -1
|
||
|
}
|
||
|
|
||
|
targetYCoordinate := float64(leftPoint.Y)
|
||
|
currentYCoordinate := leftPoint.Y
|
||
|
for i := leftPoint.X; i < rightPoint.X; i++ {
|
||
|
points = append(points, image.Pt(i, currentYCoordinate))
|
||
|
targetYCoordinate += (slope * float64(slopeSign))
|
||
|
for currentYCoordinate != int(targetYCoordinate) {
|
||
|
points = append(points, image.Pt(i, currentYCoordinate))
|
||
|
currentYCoordinate += slopeSign
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return points
|
||
|
}
|
||
|
|
||
|
func absInt(x int) int {
|
||
|
if x >= 0 {
|
||
|
return x
|
||
|
}
|
||
|
return -x
|
||
|
}
|