Start path package
This commit is contained in:
parent
61a6e03fdb
commit
1d191b3eaf
4 changed files with 0 additions and 396 deletions
|
@ -1,42 +0,0 @@
|
|||
// Copyright 2010 The draw2d Authors. All rights reserved.
|
||||
// created: 13/12/2010 by Laurent Le Goff
|
||||
|
||||
package draw2d
|
||||
|
||||
import (
|
||||
"math"
|
||||
)
|
||||
|
||||
//high level path creation
|
||||
|
||||
func Rect(path PathBuilder, x1, y1, x2, y2 float64) {
|
||||
path.MoveTo(x1, y1)
|
||||
path.LineTo(x2, y1)
|
||||
path.LineTo(x2, y2)
|
||||
path.LineTo(x1, y2)
|
||||
path.Close()
|
||||
}
|
||||
|
||||
func RoundRect(path PathBuilder, x1, y1, x2, y2, arcWidth, arcHeight float64) {
|
||||
arcWidth = arcWidth / 2
|
||||
arcHeight = arcHeight / 2
|
||||
path.MoveTo(x1, y1+arcHeight)
|
||||
path.QuadCurveTo(x1, y1, x1+arcWidth, y1)
|
||||
path.LineTo(x2-arcWidth, y1)
|
||||
path.QuadCurveTo(x2, y1, x2, y1+arcHeight)
|
||||
path.LineTo(x2, y2-arcHeight)
|
||||
path.QuadCurveTo(x2, y2, x2-arcWidth, y2)
|
||||
path.LineTo(x1+arcWidth, y2)
|
||||
path.QuadCurveTo(x1, y2, x1, y2-arcHeight)
|
||||
path.Close()
|
||||
}
|
||||
|
||||
func Ellipse(path PathBuilder, cx, cy, rx, ry float64) {
|
||||
path.ArcTo(cx, cy, rx, ry, 0, -math.Pi*2)
|
||||
path.Close()
|
||||
}
|
||||
|
||||
func Circle(path PathBuilder, cx, cy, radius float64) {
|
||||
path.ArcTo(cx, cy, radius, radius, 0, -math.Pi*2)
|
||||
path.Close()
|
||||
}
|
28
path.go
28
path.go
|
@ -1,28 +0,0 @@
|
|||
// Copyright 2010 The draw2d Authors. All rights reserved.
|
||||
// created: 21/11/2010 by Laurent Le Goff
|
||||
|
||||
package draw2d
|
||||
|
||||
// PathBuilder define method that create path
|
||||
type PathBuilder interface {
|
||||
// Return the current point of the current path
|
||||
LastPoint() (x, y float64)
|
||||
|
||||
// MoveTo start a new path at (x, y) position
|
||||
MoveTo(x, y float64)
|
||||
|
||||
// LineTo add a line to the current path
|
||||
LineTo(x, y float64)
|
||||
|
||||
// QuadCurveTo add a quadratic curve to the current path
|
||||
QuadCurveTo(cx, cy, x, y float64)
|
||||
|
||||
// CubicCurveTo add a cubic bezier curve to the current path
|
||||
CubicCurveTo(cx1, cy1, cx2, cy2, x, y float64)
|
||||
|
||||
// ArcTo add an arc to the path
|
||||
ArcTo(cx, cy, rx, ry, startAngle, angle float64)
|
||||
|
||||
// Close the current path
|
||||
Close()
|
||||
}
|
|
@ -1,147 +0,0 @@
|
|||
// Copyright 2010 The draw2d Authors. All rights reserved.
|
||||
// created: 06/12/2010 by Laurent Le Goff
|
||||
|
||||
package draw2d
|
||||
|
||||
import (
|
||||
"github.com/llgcode/draw2d/curve"
|
||||
"math"
|
||||
)
|
||||
|
||||
type PathConverter struct {
|
||||
converter LineBuilder
|
||||
ApproximationScale float64
|
||||
startX, startY, x, y float64
|
||||
}
|
||||
|
||||
func NewPathConverter(converter LineBuilder) *PathConverter {
|
||||
return &PathConverter{converter, 1, 0, 0, 0, 0}
|
||||
}
|
||||
|
||||
func (c *PathConverter) Convert(paths ...*Path) {
|
||||
for _, path := range paths {
|
||||
i := 0
|
||||
for _, cmd := range path.commands {
|
||||
switch cmd {
|
||||
case MoveTo:
|
||||
c.x, c.y = path.vertices[i], path.vertices[i+1]
|
||||
c.startX, c.startY = c.x, c.y
|
||||
if i != 0 {
|
||||
c.converter.End()
|
||||
}
|
||||
c.converter.MoveTo(c.x, c.y)
|
||||
i += 2
|
||||
case LineTo:
|
||||
c.x, c.y = path.vertices[i], path.vertices[i+1]
|
||||
c.converter.LineTo(c.x, c.y)
|
||||
c.converter.LineJoin()
|
||||
i += 2
|
||||
case QuadCurveTo:
|
||||
curve.TraceQuad(c.converter, path.vertices[i-2:], 0.5)
|
||||
c.x, c.y = path.vertices[i+2], path.vertices[i+3]
|
||||
c.converter.LineTo(c.x, c.y)
|
||||
i += 4
|
||||
case CubicCurveTo:
|
||||
curve.TraceCubic(c.converter, path.vertices[i-2:], 0.5)
|
||||
c.x, c.y = path.vertices[i+4], path.vertices[i+5]
|
||||
c.converter.LineTo(c.x, c.y)
|
||||
i += 6
|
||||
case ArcTo:
|
||||
c.x, c.y = arc(c.converter, path.vertices[i], path.vertices[i+1], path.vertices[i+2], path.vertices[i+3], path.vertices[i+4], path.vertices[i+5], c.ApproximationScale)
|
||||
c.converter.LineTo(c.x, c.y)
|
||||
i += 6
|
||||
case Close:
|
||||
c.converter.LineTo(c.startX, c.startY)
|
||||
c.converter.Close()
|
||||
}
|
||||
}
|
||||
c.converter.End()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *PathConverter) convertCommand(cmd PathCmd, vertices ...float64) int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (c *PathConverter) MoveTo(x, y float64) *PathConverter {
|
||||
c.x, c.y = x, y
|
||||
c.startX, c.startY = c.x, c.y
|
||||
c.converter.End()
|
||||
c.converter.MoveTo(c.x, c.y)
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *PathConverter) RMoveTo(dx, dy float64) *PathConverter {
|
||||
c.MoveTo(c.x+dx, c.y+dy)
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *PathConverter) LineTo(x, y float64) *PathConverter {
|
||||
c.x, c.y = x, y
|
||||
c.converter.LineTo(c.x, c.y)
|
||||
c.converter.LineJoin()
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *PathConverter) RLineTo(dx, dy float64) *PathConverter {
|
||||
c.LineTo(c.x+dx, c.y+dy)
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *PathConverter) QuadCurveTo(cx, cy, x, y float64) *PathConverter {
|
||||
curve.TraceQuad(c.converter, []float64{c.x, c.y, cx, cy, x, y}, 0.5)
|
||||
c.x, c.y = x, y
|
||||
c.converter.LineTo(c.x, c.y)
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *PathConverter) RQuadCurveTo(dcx, dcy, dx, dy float64) *PathConverter {
|
||||
c.QuadCurveTo(c.x+dcx, c.y+dcy, c.x+dx, c.y+dy)
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *PathConverter) CubicCurveTo(cx1, cy1, cx2, cy2, x, y float64) *PathConverter {
|
||||
curve.TraceCubic(c.converter, []float64{c.x, c.y, cx1, cy1, cx2, cy2, x, y}, 0.5)
|
||||
c.x, c.y = x, y
|
||||
c.converter.LineTo(c.x, c.y)
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *PathConverter) RCubicCurveTo(dcx1, dcy1, dcx2, dcy2, dx, dy float64) *PathConverter {
|
||||
c.CubicCurveTo(c.x+dcx1, c.y+dcy1, c.x+dcx2, c.y+dcy2, c.x+dx, c.y+dy)
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *PathConverter) ArcTo(cx, cy, rx, ry, startAngle, angle float64) *PathConverter {
|
||||
endAngle := startAngle + angle
|
||||
clockWise := true
|
||||
if angle < 0 {
|
||||
clockWise = false
|
||||
}
|
||||
// normalize
|
||||
if clockWise {
|
||||
for endAngle < startAngle {
|
||||
endAngle += math.Pi * 2.0
|
||||
}
|
||||
} else {
|
||||
for startAngle < endAngle {
|
||||
startAngle += math.Pi * 2.0
|
||||
}
|
||||
}
|
||||
startX := cx + math.Cos(startAngle)*rx
|
||||
startY := cy + math.Sin(startAngle)*ry
|
||||
c.MoveTo(startX, startY)
|
||||
c.x, c.y = arc(c.converter, cx, cy, rx, ry, startAngle, angle, c.ApproximationScale)
|
||||
c.converter.LineTo(c.x, c.y)
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *PathConverter) RArcTo(dcx, dcy, rx, ry, startAngle, angle float64) *PathConverter {
|
||||
c.ArcTo(c.x+dcx, c.y+dcy, rx, ry, startAngle, angle)
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *PathConverter) Close() *PathConverter {
|
||||
c.converter.Close()
|
||||
return c
|
||||
}
|
179
path_storage.go
179
path_storage.go
|
@ -1,179 +0,0 @@
|
|||
// Copyright 2010 The draw2d Authors. All rights reserved.
|
||||
// created: 21/11/2010 by Laurent Le Goff
|
||||
|
||||
package draw2d
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
)
|
||||
|
||||
type PathCmd int
|
||||
|
||||
const (
|
||||
MoveTo PathCmd = iota
|
||||
LineTo
|
||||
QuadCurveTo
|
||||
CubicCurveTo
|
||||
ArcTo
|
||||
Close
|
||||
)
|
||||
|
||||
type Path struct {
|
||||
commands []PathCmd
|
||||
vertices []float64
|
||||
x, y float64
|
||||
}
|
||||
|
||||
func NewPathStorage() (p *Path) {
|
||||
p = new(Path)
|
||||
p.commands = make([]PathCmd, 0, 256)
|
||||
p.vertices = make([]float64, 0, 256)
|
||||
return
|
||||
}
|
||||
|
||||
func (p *Path) Clear() {
|
||||
p.commands = p.commands[0:0]
|
||||
p.vertices = p.vertices[0:0]
|
||||
return
|
||||
}
|
||||
|
||||
func (p *Path) appendToPath(cmd PathCmd, vertices ...float64) {
|
||||
p.commands = append(p.commands, cmd)
|
||||
p.vertices = append(p.vertices, vertices...)
|
||||
}
|
||||
|
||||
func (src *Path) Copy() (dest *Path) {
|
||||
dest = new(Path)
|
||||
dest.commands = make([]PathCmd, len(src.commands))
|
||||
copy(dest.commands, src.commands)
|
||||
dest.vertices = make([]float64, len(src.vertices))
|
||||
copy(dest.vertices, src.vertices)
|
||||
return dest
|
||||
}
|
||||
|
||||
func (p *Path) LastPoint() (x, y float64) {
|
||||
return p.x, p.y
|
||||
}
|
||||
|
||||
func (p *Path) IsEmpty() bool {
|
||||
return len(p.commands) == 0
|
||||
}
|
||||
|
||||
func (p *Path) Close() {
|
||||
p.appendToPath(Close)
|
||||
}
|
||||
|
||||
func (p *Path) MoveTo(x, y float64) {
|
||||
p.appendToPath(MoveTo, x, y)
|
||||
|
||||
p.x = x
|
||||
p.y = y
|
||||
}
|
||||
|
||||
func (p *Path) RMoveTo(dx, dy float64) {
|
||||
x, y := p.LastPoint()
|
||||
p.MoveTo(x+dx, y+dy)
|
||||
}
|
||||
|
||||
func (p *Path) LineTo(x, y float64) {
|
||||
if len(p.commands) == 0 { //special case when no move has been done
|
||||
p.MoveTo(0, 0)
|
||||
}
|
||||
p.appendToPath(LineTo, x, y)
|
||||
p.x = x
|
||||
p.y = y
|
||||
}
|
||||
|
||||
func (p *Path) RLineTo(dx, dy float64) {
|
||||
x, y := p.LastPoint()
|
||||
p.LineTo(x+dx, y+dy)
|
||||
}
|
||||
|
||||
func (p *Path) QuadCurveTo(cx, cy, x, y float64) {
|
||||
if len(p.commands) == 0 { //special case when no move has been done
|
||||
p.MoveTo(0, 0)
|
||||
}
|
||||
p.appendToPath(QuadCurveTo, cx, cy, x, y)
|
||||
p.x = x
|
||||
p.y = y
|
||||
}
|
||||
|
||||
func (p *Path) RQuadCurveTo(dcx, dcy, dx, dy float64) {
|
||||
x, y := p.LastPoint()
|
||||
p.QuadCurveTo(x+dcx, y+dcy, x+dx, y+dy)
|
||||
}
|
||||
|
||||
func (p *Path) CubicCurveTo(cx1, cy1, cx2, cy2, x, y float64) {
|
||||
if len(p.commands) == 0 { //special case when no move has been done
|
||||
p.MoveTo(0, 0)
|
||||
}
|
||||
p.appendToPath(CubicCurveTo, cx1, cy1, cx2, cy2, x, y)
|
||||
p.x = x
|
||||
p.y = y
|
||||
}
|
||||
|
||||
func (p *Path) RCubicCurveTo(dcx1, dcy1, dcx2, dcy2, dx, dy float64) {
|
||||
x, y := p.LastPoint()
|
||||
p.CubicCurveTo(x+dcx1, y+dcy1, x+dcx2, y+dcy2, x+dx, y+dy)
|
||||
}
|
||||
|
||||
func (p *Path) ArcTo(cx, cy, rx, ry, startAngle, angle float64) {
|
||||
endAngle := startAngle + angle
|
||||
clockWise := true
|
||||
if angle < 0 {
|
||||
clockWise = false
|
||||
}
|
||||
// normalize
|
||||
if clockWise {
|
||||
for endAngle < startAngle {
|
||||
endAngle += math.Pi * 2.0
|
||||
}
|
||||
} else {
|
||||
for startAngle < endAngle {
|
||||
startAngle += math.Pi * 2.0
|
||||
}
|
||||
}
|
||||
startX := cx + math.Cos(startAngle)*rx
|
||||
startY := cy + math.Sin(startAngle)*ry
|
||||
if len(p.commands) > 0 {
|
||||
p.LineTo(startX, startY)
|
||||
} else {
|
||||
p.MoveTo(startX, startY)
|
||||
}
|
||||
p.appendToPath(ArcTo, cx, cy, rx, ry, startAngle, angle)
|
||||
p.x = cx + math.Cos(endAngle)*rx
|
||||
p.y = cy + math.Sin(endAngle)*ry
|
||||
}
|
||||
|
||||
func (p *Path) RArcTo(dcx, dcy, rx, ry, startAngle, angle float64) {
|
||||
x, y := p.LastPoint()
|
||||
p.ArcTo(x+dcx, y+dcy, rx, ry, startAngle, angle)
|
||||
}
|
||||
|
||||
func (p *Path) String() string {
|
||||
s := ""
|
||||
j := 0
|
||||
for _, cmd := range p.commands {
|
||||
switch cmd {
|
||||
case MoveTo:
|
||||
s += fmt.Sprintf("MoveTo: %f, %f\n", p.vertices[j], p.vertices[j+1])
|
||||
j = j + 2
|
||||
case LineTo:
|
||||
s += fmt.Sprintf("LineTo: %f, %f\n", p.vertices[j], p.vertices[j+1])
|
||||
j = j + 2
|
||||
case QuadCurveTo:
|
||||
s += fmt.Sprintf("QuadCurveTo: %f, %f, %f, %f\n", p.vertices[j], p.vertices[j+1], p.vertices[j+2], p.vertices[j+3])
|
||||
j = j + 4
|
||||
case CubicCurveTo:
|
||||
s += fmt.Sprintf("CubicCurveTo: %f, %f, %f, %f, %f, %f\n", p.vertices[j], p.vertices[j+1], p.vertices[j+2], p.vertices[j+3], p.vertices[j+4], p.vertices[j+5])
|
||||
j = j + 6
|
||||
case ArcTo:
|
||||
s += fmt.Sprintf("ArcTo: %f, %f, %f, %f, %f, %f\n", p.vertices[j], p.vertices[j+1], p.vertices[j+2], p.vertices[j+3], p.vertices[j+4], p.vertices[j+5])
|
||||
j = j + 6
|
||||
case Close:
|
||||
s += "Close\n"
|
||||
}
|
||||
}
|
||||
return s
|
||||
}
|
Loading…
Reference in a new issue