mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 18:58:54 +01:00
parent
599571c7a7
commit
d2f6d8593b
@ -94,23 +94,31 @@ func (g *Game) Draw(screen *ebiten.Image) {
|
||||
target = g.offscreen
|
||||
}
|
||||
|
||||
joins := []vector.LineJoin{
|
||||
vector.LineJoinMiter,
|
||||
vector.LineJoinMiter,
|
||||
vector.LineJoinBevel,
|
||||
vector.LineJoinRound,
|
||||
}
|
||||
caps := []vector.LineCap{
|
||||
vector.LineCapButt,
|
||||
vector.LineCapRound,
|
||||
vector.LineCapSquare,
|
||||
}
|
||||
|
||||
ow, oh := target.Size()
|
||||
size := min(ow/5, oh/4)
|
||||
offsetX, offsetY := (ow-size*4)/2, (oh-size*3)/2
|
||||
size := min(ow/(len(joins)+1), oh/(len(caps)+1))
|
||||
offsetX, offsetY := (ow-size*len(joins))/2, (oh-size*len(caps))/2
|
||||
|
||||
// Render the lines on the target.
|
||||
for j := 0; j < 3; j++ {
|
||||
for i, join := range []vector.LineJoin{
|
||||
vector.LineJoinMiter,
|
||||
vector.LineJoinMiter,
|
||||
vector.LineJoinBevel,
|
||||
vector.LineJoinRound} {
|
||||
for j, cap := range caps {
|
||||
for i, join := range joins {
|
||||
r := image.Rect(i*size+offsetX, j*size+offsetY, (i+1)*size+offsetX, (j+1)*size+offsetY)
|
||||
miterLimit := float32(5)
|
||||
if i == 1 {
|
||||
miterLimit = 10
|
||||
}
|
||||
g.drawLine(target, r, join, miterLimit)
|
||||
g.drawLine(target, r, cap, join, miterLimit)
|
||||
}
|
||||
}
|
||||
|
||||
@ -127,7 +135,7 @@ Press C to switch to draw the center lines.`
|
||||
ebitenutil.DebugPrint(screen, msg)
|
||||
}
|
||||
|
||||
func (g *Game) drawLine(screen *ebiten.Image, region image.Rectangle, join vector.LineJoin, miterLimit float32) {
|
||||
func (g *Game) drawLine(screen *ebiten.Image, region image.Rectangle, cap vector.LineCap, join vector.LineJoin, miterLimit float32) {
|
||||
c0x := float64(region.Min.X + region.Dx()/4)
|
||||
c0y := float64(region.Min.Y + region.Dy()/4)
|
||||
c1x := float64(region.Max.X - region.Dx()/4)
|
||||
@ -146,6 +154,7 @@ func (g *Game) drawLine(screen *ebiten.Image, region image.Rectangle, join vecto
|
||||
|
||||
// Draw the main line in white.
|
||||
op := &vector.StrokeOptions{}
|
||||
op.LineCap = cap
|
||||
op.LineJoin = join
|
||||
op.MiterLimit = miterLimit
|
||||
op.Width = float32(r / 2)
|
||||
|
@ -348,6 +348,15 @@ func (p *Path) AppendVerticesAndIndicesForFilling(vertices []ebiten.Vertex, indi
|
||||
return vertices, indices
|
||||
}
|
||||
|
||||
// LineCap represents the way in which how the ends of the stroke are rendered.
|
||||
type LineCap int
|
||||
|
||||
const (
|
||||
LineCapButt LineCap = iota
|
||||
LineCapRound
|
||||
LineCapSquare
|
||||
)
|
||||
|
||||
// LineJoin represents the way in which how two segments are joined.
|
||||
type LineJoin int
|
||||
|
||||
@ -362,6 +371,10 @@ type StrokeOptions struct {
|
||||
// Width is the stroke width in pixels.
|
||||
Width float32
|
||||
|
||||
// LineCap is the way in which how the ends of the stroke are rendered.
|
||||
// The default (zero) value is LineCapButt.
|
||||
LineCap LineCap
|
||||
|
||||
// LineJoin is the way in which how two segments are joined.
|
||||
// The default (zero) value is LineJoiMiter.
|
||||
LineJoin LineJoin
|
||||
@ -511,6 +524,68 @@ func (p *Path) AppendVerticesAndIndicesForStroke(vertices []ebiten.Vertex, indic
|
||||
vertices, indices = arc.AppendVerticesAndIndicesForFilling(vertices, indices)
|
||||
}
|
||||
}
|
||||
|
||||
if len(rects) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
switch op.LineCap {
|
||||
case LineCapButt:
|
||||
// Do nothing.
|
||||
|
||||
case LineCapRound:
|
||||
startR, endR := rects[0], rects[len(rects)-1]
|
||||
{
|
||||
c := point{
|
||||
x: (startR[0].x + startR[2].x) / 2,
|
||||
y: (startR[0].y + startR[2].y) / 2,
|
||||
}
|
||||
a := float32(math.Atan2(float64(startR[0].y-startR[2].y), float64(startR[0].x-startR[2].x)))
|
||||
var arc Path
|
||||
arc.MoveTo(startR[0].x, startR[0].y)
|
||||
arc.Arc(c.x, c.y, op.Width/2, a, a+math.Pi, CounterClockwise)
|
||||
vertices, indices = arc.AppendVerticesAndIndicesForFilling(vertices, indices)
|
||||
}
|
||||
{
|
||||
c := point{
|
||||
x: (endR[1].x + endR[3].x) / 2,
|
||||
y: (endR[1].y + endR[3].y) / 2,
|
||||
}
|
||||
a := float32(math.Atan2(float64(endR[1].y-endR[3].y), float64(endR[1].x-endR[3].x)))
|
||||
var arc Path
|
||||
arc.MoveTo(endR[1].x, endR[1].y)
|
||||
arc.Arc(c.x, c.y, op.Width/2, a, a+math.Pi, Clockwise)
|
||||
vertices, indices = arc.AppendVerticesAndIndicesForFilling(vertices, indices)
|
||||
}
|
||||
|
||||
case LineCapSquare:
|
||||
startR, endR := rects[0], rects[len(rects)-1]
|
||||
{
|
||||
a := math.Atan2(float64(startR[0].y-startR[1].y), float64(startR[0].x-startR[1].x))
|
||||
s, c := math.Sincos(a)
|
||||
dx, dy := float32(c)*op.Width/2, float32(s)*op.Width/2
|
||||
|
||||
var quad Path
|
||||
quad.MoveTo(startR[0].x, startR[0].y)
|
||||
quad.LineTo(startR[0].x+dx, startR[0].y+dy)
|
||||
quad.LineTo(startR[2].x+dx, startR[2].y+dy)
|
||||
quad.LineTo(startR[2].x, startR[2].y)
|
||||
vertices, indices = quad.AppendVerticesAndIndicesForFilling(vertices, indices)
|
||||
}
|
||||
{
|
||||
a := math.Atan2(float64(endR[1].y-endR[0].y), float64(endR[1].x-endR[0].x))
|
||||
s, c := math.Sincos(a)
|
||||
dx, dy := float32(c)*op.Width/2, float32(s)*op.Width/2
|
||||
|
||||
var quad Path
|
||||
quad.MoveTo(endR[1].x, endR[1].y)
|
||||
quad.LineTo(endR[1].x+dx, endR[1].y+dy)
|
||||
quad.LineTo(endR[3].x+dx, endR[3].y+dy)
|
||||
quad.LineTo(endR[3].x, endR[3].y)
|
||||
vertices, indices = quad.AppendVerticesAndIndicesForFilling(vertices, indices)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return vertices, indices
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user