-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patharc.rb
More file actions
74 lines (62 loc) · 1.88 KB
/
arc.rb
File metadata and controls
74 lines (62 loc) · 1.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
class Arc
# Generate the bezier points needed to draw a cicle arc, taken from
# http://hansmuller-flex.blogspot.com.au/2011/04/approximating-circular-arc-with-cubic.html
# Works for 90 degrees
MAGIC = 4.0/3.0 * (Math::sqrt(2) -1)
# transform the points around the origin by the angle
def self.rotate(angle, points)
a = Math::PI * angle / 180.0
c = Math::cos(a)
s = Math::sin(a)
points = [points] unless Array === points[0]
points.map do |x,y|
[c * x + -s * y, s * x + c * y]
end
end
# Given a radius and an angle, give us the centre point relative
# to the origin
def self.centre(angle, radius)
a = Math::PI * angle / 180.0
x = Math::cos(a) * radius
y = Math::sin(a) * radius
[x, y]
end
# Return an array of 4 point pairs, the radius is the origin.
# They will be suitable for putting into bezier curve algorithms
def self.arc_points(radius, start_angle, end_angle, offset: [0,0])
curves = []
quarter = [[radius, 0],
[radius, radius * MAGIC],
[radius * MAGIC, radius],
[0, radius]]
end_angle += 360 while start_angle > end_angle
angle = end_angle - start_angle
# The < 90 degree arc
arc = (angle % 90)
a = Math::PI * arc / 180.0
c = Math.cos(a/2)
s = Math.sin(a/2)
t = 4.0/3.0 * (1 - c)/s
x4 = radius * c
y4 = radius * s
x1 = x4
y1 = -y4
x2 = x1 + t * y4
y2 = y1 + t * x4
x3 = x2
y3 = -y2
arc_points = [[x1,y1], [x2,y2], [x3,y3], [x4,y4]]
# arc_points needs to be rotated arc/2 to get it onto the origin
curves << rotate(start_angle + arc * 0.5, arc_points)
rot = start_angle + arc
(angle / 90).floor.times do
curves << rotate(rot, quarter)
rot += 90
end
curves.map do |c|
c.map do |x,y|
[x + offset[0], y + offset[1]]
end
end
end
end