/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
  3. package curve
  4. import (
  5. "math"
  6. )
  7. const (
  8. CurveRecursionLimit = 32
  9. )
  10. // X1, Y1, X2, Y2, X3, Y3, X4, Y4 float64
  11. type CubicCurveFloat64 [8]float64
  12. type LineTracer interface {
  13. LineTo(x, y float64)
  14. }
  15. func (c *CubicCurveFloat64) Subdivide(c1, c2 *CubicCurveFloat64) (x23, y23 float64) {
  16. // Calculate all the mid-points of the line segments
  17. //----------------------
  18. c1[0], c1[1] = c[0], c[1]
  19. c2[6], c2[7] = c[6], c[7]
  20. c1[2] = (c[0] + c[2]) / 2
  21. c1[3] = (c[1] + c[3]) / 2
  22. x23 = (c[2] + c[4]) / 2
  23. y23 = (c[3] + c[5]) / 2
  24. c2[4] = (c[4] + c[6]) / 2
  25. c2[5] = (c[5] + c[7]) / 2
  26. c1[4] = (c1[2] + x23) / 2
  27. c1[5] = (c1[3] + y23) / 2
  28. c2[2] = (x23 + c2[4]) / 2
  29. c2[3] = (y23 + c2[5]) / 2
  30. c1[6] = (c1[4] + c2[2]) / 2
  31. c1[7] = (c1[5] + c2[3]) / 2
  32. c2[0], c2[1] = c1[6], c1[7]
  33. return
  34. }
  35. func (curve *CubicCurveFloat64) Segment(t LineTracer, flattening_threshold float64) {
  36. var curves [CurveRecursionLimit]CubicCurveFloat64
  37. curves[0] = *curve
  38. i := 0
  39. // current curve
  40. var c *CubicCurveFloat64
  41. var dx, dy, d2, d3 float64
  42. for i >= 0 {
  43. c = &curves[i]
  44. dx = c[6] - c[0]
  45. dy = c[7] - c[1]
  46. d2 = math.Abs(((c[2]-c[6])*dy - (c[3]-c[7])*dx))
  47. d3 = math.Abs(((c[4]-c[6])*dy - (c[5]-c[7])*dx))
  48. if (d2+d3)*(d2+d3) < flattening_threshold*(dx*dx+dy*dy) || i == len(curves)-1 {
  49. t.LineTo(c[6], c[7])
  50. i--
  51. } else {
  52. // second half of bezier go lower onto the stack
  53. c.Subdivide(&curves[i+1], &curves[i])
  54. i++
  55. }
  56. }
  57. }