kopia lustrzana https://github.com/rastapasta/mapscii
💖 adding stroke-width support for (poly)lines!
rodzic
410d3aba4f
commit
7bfe9bb57b
|
@ -44,11 +44,15 @@ module.exports = class Canvas
|
||||||
position = @_project x, y
|
position = @_project x, y
|
||||||
@buffer.writeText text, position[0], position[1], color, center
|
@buffer.writeText text, position[0], position[1], color, center
|
||||||
|
|
||||||
polyline: (points, color) ->
|
line: (from, to, color, width = 1) ->
|
||||||
|
from = @_project from[0], from[1]
|
||||||
|
to = @_project to[0], to[1]
|
||||||
|
@_line from, to, color, width
|
||||||
|
|
||||||
|
polyline: (points, color, width = 1) ->
|
||||||
projected = (@_project point[0], point[1] for point in points)
|
projected = (@_project point[0], point[1] for point in points)
|
||||||
for i in [1...projected.length]
|
for i in [1...projected.length]
|
||||||
bresenham projected[i-1]..., projected[i]...,
|
@_line projected[i-1], projected[i], width, color
|
||||||
(x, y) => @buffer.setPixel x, y, color
|
|
||||||
|
|
||||||
setBackground: (color) ->
|
setBackground: (color) ->
|
||||||
@buffer.setGlobalBackground color
|
@buffer.setGlobalBackground color
|
||||||
|
@ -77,9 +81,51 @@ module.exports = class Canvas
|
||||||
for i in [0...triangles.length] by 3
|
for i in [0...triangles.length] by 3
|
||||||
@_filledTriangle extract(triangles[i]), extract(triangles[i+1]), extract(triangles[i+2]), color
|
@_filledTriangle extract(triangles[i]), extract(triangles[i+1]), extract(triangles[i+2]), color
|
||||||
|
|
||||||
_bresenham: (pointA, pointB) ->
|
# Inspired by Alois Zingl's "The Beauty of Bresenham's Algorithm"
|
||||||
bresenham pointA[0], pointA[1],
|
# -> http://members.chello.at/~easyfilter/bresenham.html
|
||||||
pointB[0], pointB[1]
|
_line: (pointA, pointB, width, color) ->
|
||||||
|
|
||||||
|
# Fall back to width-less bresenham algorithm if we dont have a width
|
||||||
|
unless width = Math.max 0, width-1
|
||||||
|
return bresenham pointA[0], pointA[1], pointB[0], pointB[1],
|
||||||
|
(x, y) => @buffer.setPixel x, y, color
|
||||||
|
|
||||||
|
[x0, y0] = pointA
|
||||||
|
[x1, y1] = pointB
|
||||||
|
dx = Math.abs x1-x0
|
||||||
|
sx = if x0 < x1 then 1 else -1
|
||||||
|
dy = Math.abs y1-y0
|
||||||
|
sy = if y0 < y1 then 1 else -1
|
||||||
|
|
||||||
|
err = dx-dy
|
||||||
|
|
||||||
|
ed = if dx+dy is 0 then 1 else Math.sqrt dx*dx+dy*dy
|
||||||
|
|
||||||
|
width = (width+1)/2
|
||||||
|
loop
|
||||||
|
@buffer.setPixel x0, y0, color
|
||||||
|
e2 = err
|
||||||
|
x2 = x0
|
||||||
|
|
||||||
|
if 2*e2 >= -dx
|
||||||
|
e2 += dy
|
||||||
|
y2 = y0
|
||||||
|
while e2 < ed*width && (y1 != y2 || dx > dy)
|
||||||
|
@buffer.setPixel x0, y2 += sy, color
|
||||||
|
e2 += dx
|
||||||
|
break if x0 is x1
|
||||||
|
e2 = err
|
||||||
|
err -= dy
|
||||||
|
x0 += sx
|
||||||
|
|
||||||
|
if 2*e2 <= dy
|
||||||
|
e2 = dx-e2
|
||||||
|
while e2 < ed*width && (x1 != x2 || dx < dy)
|
||||||
|
@buffer.setPixel x2 += sx, y0, color
|
||||||
|
e2 += dy
|
||||||
|
break if y0 is y1
|
||||||
|
err += dx
|
||||||
|
y0 += sy
|
||||||
|
|
||||||
_project: (x, y) ->
|
_project: (x, y) ->
|
||||||
point = vec2.transformMat2d vec2.create(), vec2.fromValues(x, y), @matrix
|
point = vec2.transformMat2d vec2.create(), vec2.fromValues(x, y), @matrix
|
||||||
|
@ -94,6 +140,10 @@ module.exports = class Canvas
|
||||||
@_filledTriangle pointA, pointB, pointC, color
|
@_filledTriangle pointA, pointB, pointC, color
|
||||||
@_filledTriangle pointC, pointB, pointD, color
|
@_filledTriangle pointC, pointB, pointD, color
|
||||||
|
|
||||||
|
_bresenham: (pointA, pointB) ->
|
||||||
|
bresenham pointA[0], pointA[1],
|
||||||
|
pointB[0], pointB[1]
|
||||||
|
|
||||||
# Draws a filled triangle
|
# Draws a filled triangle
|
||||||
_filledTriangle: (pointA, pointB, pointC, color) ->
|
_filledTriangle: (pointA, pointB, pointC, color) ->
|
||||||
a = @_bresenham pointB, pointC
|
a = @_bresenham pointB, pointC
|
||||||
|
@ -103,7 +153,6 @@ module.exports = class Canvas
|
||||||
# Filter out any points outside of the visible area
|
# Filter out any points outside of the visible area
|
||||||
# TODO: benchmark - is it more effective to filter double points, or does
|
# TODO: benchmark - is it more effective to filter double points, or does
|
||||||
# it req more computing time than actually setting points multiple times?
|
# it req more computing time than actually setting points multiple times?
|
||||||
|
|
||||||
last = null
|
last = null
|
||||||
points = a.concat(b).concat(c)
|
points = a.concat(b).concat(c)
|
||||||
.filter (point) => 0 <= point.y < @height
|
.filter (point) => 0 <= point.y < @height
|
||||||
|
|
Ładowanie…
Reference in New Issue