vector: Add QuadraticCurve

Updates #741
This commit is contained in:
Hajime Hoshi 2019-12-28 14:57:50 +09:00
parent cb1dcc37a0
commit d39dbc6a88
4 changed files with 63 additions and 7 deletions

View File

@ -46,7 +46,14 @@ func drawEbitenText(screen *ebiten.Image) {
path.LineTo(70, 30) path.LineTo(70, 30)
path.LineTo(70, 20) path.LineTo(70, 20)
// TODO: Draw other letters like B, I, T, E, N // B
path.MoveTo(80, 20)
path.LineTo(80, 70)
path.LineTo(100, 70)
path.QuadraticCurveTo(130, 57.5, 100, 45)
path.QuadraticCurveTo(130, 32.5, 100, 20)
// TODO: Draw other letters like I, T, E, N
path.Fill(screen, color.White) path.Fill(screen, color.White)
} }

View File

@ -34,7 +34,7 @@ func InTriangle(pt, pt0, pt1, pt2 Point) bool {
c0 := cross(Vector{pt.X - pt0.X, pt.Y - pt0.Y}, Vector{pt1.X - pt0.X, pt1.Y - pt0.Y}) c0 := cross(Vector{pt.X - pt0.X, pt.Y - pt0.Y}, Vector{pt1.X - pt0.X, pt1.Y - pt0.Y})
c1 := cross(Vector{pt.X - pt1.X, pt.Y - pt1.Y}, Vector{pt2.X - pt1.X, pt2.Y - pt1.Y}) c1 := cross(Vector{pt.X - pt1.X, pt.Y - pt1.Y}, Vector{pt2.X - pt1.X, pt2.Y - pt1.Y})
c2 := cross(Vector{pt.X - pt2.X, pt.Y - pt2.Y}, Vector{pt0.X - pt2.X, pt0.Y - pt2.Y}) c2 := cross(Vector{pt.X - pt2.X, pt.Y - pt2.Y}, Vector{pt0.X - pt2.X, pt0.Y - pt2.Y})
return (c0 < 0 && c1 < 0 && c2 < 0) || (c0 > 0 && c1 > 0 && c2 > 0) return (c0 <= 0 && c1 <= 0 && c2 <= 0) || (c0 >= 0 && c1 >= 0 && c2 >= 0)
} }
func Triangulate(pts []Point) []uint16 { func Triangulate(pts []Point) []uint16 {
@ -60,12 +60,12 @@ dup:
// Determine the direction of the polygon from the upper-left point. // Determine the direction of the polygon from the upper-left point.
var upperLeft int var upperLeft int
for _, i := range currentIndices { for ci, i := range currentIndices {
if pts[upperLeft].X < pts[i].X { if pts[upperLeft].X < pts[i].X {
upperLeft = int(i) upperLeft = int(ci)
} }
if pts[upperLeft].X == pts[i].X && pts[upperLeft].Y < pts[i].Y { if pts[upperLeft].X == pts[i].X && pts[upperLeft].Y < pts[i].Y {
upperLeft = int(i) upperLeft = int(ci)
} }
} }
i0, i1, i2 := adjacentIndices(currentIndices, upperLeft) i0, i1, i2 := adjacentIndices(currentIndices, upperLeft)

View File

@ -145,6 +145,15 @@ func TestTriangulate(t *testing.T) {
}, },
Out: []uint16{2, 0, 1}, Out: []uint16{2, 0, 1},
}, },
{
In: []Point{
{0, 0},
{1, 1},
{0, 1},
{0, 0.5},
},
Out: []uint16{2, 0, 1},
},
{ {
In: []Point{ In: []Point{
{0, 0}, {0, 0},
@ -178,7 +187,33 @@ func TestTriangulate(t *testing.T) {
{3, 4}, {3, 4},
{3, 3}, {3, 3},
}, },
Out: []uint16{9, 0, 1, 1, 2, 3, 1, 3, 4, 9, 1, 4, 8, 5, 6, 8, 6, 7}, Out: []uint16{9, 0, 1, 1, 2, 3, 1, 3, 4, 1, 4, 5, 5, 6, 7, 5, 7, 8, 9, 1, 5},
},
{
In: []Point{
{0, 0},
{0, 5},
{2, 5},
{3, 3},
{2, 2},
{3, 1},
{2, 0},
},
Out: []uint16{6, 0, 1, 1, 2, 3, 1, 3, 4, 6, 1, 4, 6, 4, 5},
},
{
In: []Point{
{0, 0},
{0, 5},
{2, 5},
{2, 5},
{3, 3},
{2, 2},
{2, 2},
{3, 1},
{2, 0},
},
Out: []uint16{8, 0, 1, 1, 2, 4, 1, 4, 5, 8, 1, 5, 8, 5, 7},
}, },
} }
for _, tc := range tests { for _, tc := range tests {

View File

@ -48,12 +48,26 @@ func (p *Path) MoveTo(x, y float32) {
// LineTo updates the current position to (x, y). // LineTo updates the current position to (x, y).
func (p *Path) LineTo(x, y float32) { func (p *Path) LineTo(x, y float32) {
if len(p.segs) == 0 { if len(p.segs) == 0 {
p.segs = append(p.segs, []math.Point{{X: 0, Y: 0}}) p.segs = append(p.segs, []math.Point{p.cur})
} }
p.segs[len(p.segs)-1] = append(p.segs[len(p.segs)-1], math.Point{X: x, Y: y}) p.segs[len(p.segs)-1] = append(p.segs[len(p.segs)-1], math.Point{X: x, Y: y})
p.cur = math.Point{X: x, Y: y} p.cur = math.Point{X: x, Y: y}
} }
func (p *Path) QuadraticCurveTo(cpx, cpy, x, y float32) {
c := p.cur
dist := float64((x-c.X)*(x-c.X) + (y-c.Y)*(y-c.Y))
num := 1.0
for num*num < dist {
num *= 2
}
for t := float32(0.0); t <= 1; t += 1.0 / 128.0 {
xf := t*t*x + 2*t*(1-t)*cpx + (1-t)*(1-t)*c.X
yf := t*t*y + 2*t*(1-t)*cpy + (1-t)*(1-t)*c.Y
p.LineTo(xf, yf)
}
}
func (p *Path) Fill(dst *ebiten.Image, clr color.Color) { func (p *Path) Fill(dst *ebiten.Image, clr color.Color) {
var vertices []ebiten.Vertex var vertices []ebiten.Vertex
var indices []uint16 var indices []uint16