PageRenderTime 102ms CodeModel.GetById 30ms app.highlight 11ms RepoModel.GetById 60ms app.codeStats 0ms

/draw2d/curve/cubic_float64.go

https://code.google.com/p/draw2d/
Go | 67 lines | 50 code | 10 blank | 7 comment | 5 complexity | c4658af1fdc06d28f92e499ee81dce8c MD5 | raw file
 1// Copyright 2010 The draw2d Authors. All rights reserved.
 2// created: 17/05/2011 by Laurent Le Goff
 3package curve
 4
 5import (
 6	"math"
 7)
 8
 9const (
10	CurveRecursionLimit = 32
11)
12
13//	X1, Y1, X2, Y2, X3, Y3, X4, Y4 float64
14type CubicCurveFloat64 [8]float64
15
16type LineTracer interface {
17	LineTo(x, y float64)
18}
19
20func (c *CubicCurveFloat64) Subdivide(c1, c2 *CubicCurveFloat64) (x23, y23 float64) {
21	// Calculate all the mid-points of the line segments
22	//----------------------
23	c1[0], c1[1] = c[0], c[1]
24	c2[6], c2[7] = c[6], c[7]
25	c1[2] = (c[0] + c[2]) / 2
26	c1[3] = (c[1] + c[3]) / 2
27	x23 = (c[2] + c[4]) / 2
28	y23 = (c[3] + c[5]) / 2
29	c2[4] = (c[4] + c[6]) / 2
30	c2[5] = (c[5] + c[7]) / 2
31	c1[4] = (c1[2] + x23) / 2
32	c1[5] = (c1[3] + y23) / 2
33	c2[2] = (x23 + c2[4]) / 2
34	c2[3] = (y23 + c2[5]) / 2
35	c1[6] = (c1[4] + c2[2]) / 2
36	c1[7] = (c1[5] + c2[3]) / 2
37	c2[0], c2[1] = c1[6], c1[7]
38	return
39}
40
41func (curve *CubicCurveFloat64) Segment(t LineTracer, flattening_threshold float64) {
42	var curves [CurveRecursionLimit]CubicCurveFloat64
43	curves[0] = *curve
44	i := 0
45	// current curve
46	var c *CubicCurveFloat64
47
48	var dx, dy, d2, d3 float64
49
50	for i >= 0 {
51		c = &curves[i]
52		dx = c[6] - c[0]
53		dy = c[7] - c[1]
54
55		d2 = math.Abs(((c[2]-c[6])*dy - (c[3]-c[7])*dx))
56		d3 = math.Abs(((c[4]-c[6])*dy - (c[5]-c[7])*dx))
57
58		if (d2+d3)*(d2+d3) < flattening_threshold*(dx*dx+dy*dy) || i == len(curves)-1 {
59			t.LineTo(c[6], c[7])
60			i--
61		} else {
62			// second half of bezier go lower onto the stack
63			c.Subdivide(&curves[i+1], &curves[i])
64			i++
65		}
66	}
67}