A rendering engine library for Go supporting both SDL2 and WebAssembly (HTML Canvas) targets.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

103 lines
1.9 KiB

  1. package render
  2. import (
  3. "math"
  4. )
  5. // IterLine is a generator that returns the X,Y coordinates to draw a line.
  6. // https://en.wikipedia.org/wiki/Digital_differential_analyzer_(graphics_algorithm)
  7. func IterLine(p1 Point, p2 Point) chan Point {
  8. var (
  9. x1 = p1.X
  10. y1 = p1.Y
  11. x2 = p2.X
  12. y2 = p2.Y
  13. )
  14. generator := make(chan Point)
  15. go func() {
  16. var (
  17. dx = float64(x2 - x1)
  18. dy = float64(y2 - y1)
  19. )
  20. var step float64
  21. if math.Abs(dx) >= math.Abs(dy) {
  22. step = math.Abs(dx)
  23. } else {
  24. step = math.Abs(dy)
  25. }
  26. dx = dx / step
  27. dy = dy / step
  28. x := float64(x1)
  29. y := float64(y1)
  30. for i := 0; i <= int(step); i++ {
  31. generator <- NewPoint(int(x), int(y))
  32. x += dx
  33. y += dy
  34. }
  35. close(generator)
  36. }()
  37. return generator
  38. }
  39. // IterRect loops through all the points forming a rectangle between the
  40. // top-left point and the bottom-right point.
  41. func IterRect(p1, p2 Point) chan Point {
  42. generator := make(chan Point)
  43. go func() {
  44. var (
  45. TopLeft = p1
  46. BottomRight = p2
  47. TopRight = Point{
  48. X: BottomRight.X,
  49. Y: TopLeft.Y,
  50. }
  51. BottomLeft = Point{
  52. X: TopLeft.X,
  53. Y: BottomRight.Y,
  54. }
  55. dedupe = map[Point]interface{}{}
  56. )
  57. // Trace all four edges and yield it.
  58. var edges = []struct {
  59. A Point
  60. B Point
  61. }{
  62. {TopLeft, TopRight},
  63. {TopLeft, BottomLeft},
  64. {BottomLeft, BottomRight},
  65. {TopRight, BottomRight},
  66. }
  67. for _, edge := range edges {
  68. for pt := range IterLine(edge.A, edge.B) {
  69. if _, ok := dedupe[pt]; !ok {
  70. generator <- pt
  71. dedupe[pt] = nil
  72. }
  73. }
  74. }
  75. close(generator)
  76. }()
  77. return generator
  78. }
  79. // IterEllipse iterates an Ellipse using two Points as the top-left and
  80. // bottom-right corners of a rectangle that encompasses the ellipse.
  81. func IterEllipse(A, B Point) chan Point {
  82. var (
  83. width = AbsInt(B.X - A.X)
  84. height = AbsInt(B.Y - A.Y)
  85. radius = NewPoint(width/2, height/2)
  86. center = NewPoint(AbsInt(B.X-radius.X), AbsInt(B.Y-radius.Y))
  87. )
  88. return MidpointEllipse(center, radius)
  89. }