vector: add StrokeOptions.MiterLimit

This commit is contained in:
Hajime Hoshi 2022-10-14 23:20:16 +09:00
parent 04680ff761
commit 225bf1bbb4
2 changed files with 22 additions and 8 deletions

View File

@ -95,14 +95,22 @@ func (g *Game) Draw(screen *ebiten.Image) {
} }
ow, oh := target.Size() ow, oh := target.Size()
size := min(ow/4, oh/4) size := min(ow/5, oh/4)
offsetX, offsetY := (ow-size*3)/2, (oh-size*3)/2 offsetX, offsetY := (ow-size*4)/2, (oh-size*3)/2
// Render the lines on the target. // Render the lines on the target.
for j := 0; j < 3; j++ { for j := 0; j < 3; j++ {
for i, join := range []vector.LineJoin{vector.LineJoinMiter, vector.LineJoinBevel, vector.LineJoinRound} { for i, join := range []vector.LineJoin{
vector.LineJoinMiter,
vector.LineJoinMiter,
vector.LineJoinBevel,
vector.LineJoinRound} {
r := image.Rect(i*size+offsetX, j*size+offsetY, (i+1)*size+offsetX, (j+1)*size+offsetY) r := image.Rect(i*size+offsetX, j*size+offsetY, (i+1)*size+offsetX, (j+1)*size+offsetY)
g.drawLine(target, r, join) miterLimit := float32(5)
if i == 1 {
miterLimit = 10
}
g.drawLine(target, r, join, miterLimit)
} }
} }
@ -119,7 +127,7 @@ Press C to switch to draw the center lines.`
ebitenutil.DebugPrint(screen, msg) ebitenutil.DebugPrint(screen, msg)
} }
func (g *Game) drawLine(screen *ebiten.Image, region image.Rectangle, join vector.LineJoin) { func (g *Game) drawLine(screen *ebiten.Image, region image.Rectangle, join vector.LineJoin, miterLimit float32) {
c0x := float64(region.Min.X + region.Dx()/4) c0x := float64(region.Min.X + region.Dx()/4)
c0y := float64(region.Min.Y + region.Dy()/4) c0y := float64(region.Min.Y + region.Dy()/4)
c1x := float64(region.Max.X - region.Dx()/4) c1x := float64(region.Max.X - region.Dx()/4)
@ -137,6 +145,7 @@ func (g *Game) drawLine(screen *ebiten.Image, region image.Rectangle, join vecto
// Draw the main line in white. // Draw the main line in white.
op := &vector.StrokeOptions{} op := &vector.StrokeOptions{}
op.LineJoin = join op.LineJoin = join
op.MiterLimit = miterLimit
op.Width = float32(r / 2) op.Width = float32(r / 2)
vs, is := path.AppendVerticesAndIndicesForStroke(g.vertices[:0], g.indices[:0], op) vs, is := path.AppendVerticesAndIndicesForStroke(g.vertices[:0], g.indices[:0], op)
for i := range vs { for i := range vs {

View File

@ -365,6 +365,12 @@ type StrokeOptions struct {
// LineJoin is the way in which how two segments are joined. // LineJoin is the way in which how two segments are joined.
// The default (zero) value is LineJoiMiter. // The default (zero) value is LineJoiMiter.
LineJoin LineJoin LineJoin LineJoin
// MiterLimit is the miter limit for LineJoinMiter.
// For details, see https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-miterlimit.
//
// The default (zero) value is 0.
MiterLimit float32
} }
// AppendVerticesAndIndicesForStroke appends vertices and indices to render a stroke of this path and returns them. // AppendVerticesAndIndicesForStroke appends vertices and indices to render a stroke of this path and returns them.
@ -460,10 +466,9 @@ func (p *Path) AppendVerticesAndIndicesForStroke(vertices []ebiten.Vertex, indic
switch op.LineJoin { switch op.LineJoin {
case LineJoinMiter: case LineJoinMiter:
// TODO: Enable to configure this.
const miterLimit = 10
delta := math.Pi - da delta := math.Pi - da
exceed := math.Abs(1/math.Sin(float64(delta/2))) > miterLimit exceed := float32(math.Abs(1/math.Sin(float64(delta/2)))) > op.MiterLimit
var quad Path var quad Path
quad.MoveTo(c.x, c.y) quad.MoveTo(c.x, c.y)
if da < math.Pi { if da < math.Pi {