Skip to content

Commit 4d9a39e

Browse files
committed
refine circles sketch
1 parent 9c6b3f5 commit 4d9a39e

File tree

5 files changed

+21
-56
lines changed

5 files changed

+21
-56
lines changed

processing_app/library/vecmath/vec2d/circles.rb

+11-7
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,25 @@
11
#!/usr/bin/env jruby
22
require 'propane'
33

4+
# The sketch class
45
class Circles < Propane::App
56
load_library :circles
67

78
def settings
89
size(800, 600, P2D)
910
end
1011

11-
## To be overriden by the Presentation Code.
1212
def setup
1313
sketch_title 'Circles'
1414
color_mode(HSB, 360, 100, 100, 100)
15-
@c = rand(360)
16-
@points = TPoints.new
17-
3.times { @points << TPoint.new(Vec2D.new(rand(5..width - 5), rand(5..height - 5))) }
18-
background 0
15+
reset
1916
ellipse_mode(RADIUS)
2017
end
2118

2219
def draw
2320
fill(0, 0, 0)
2421
no_stroke
25-
rect(0, 0, width, height) if (frame_count % 8_000).zero?
22+
reset if (frame_count % 8_000).zero?
2623
@points.each do |point|
2724
# change direction sometimes
2825
point.direction Vec2D.random if rand > 0.96
@@ -39,12 +36,19 @@ def draw
3936
end
4037

4138
def draw_circle(pts)
42-
circumcircle = Circumcircle.new(@points.vec)
39+
circumcircle = Circumcircle.new(@points.positions)
4340
circumcircle.calculate
4441
center_point = circumcircle.center
4542
radius = circumcircle.radius
4643
ellipse(center_point.x, center_point.y, radius, radius)
4744
end
45+
46+
def reset
47+
@c = rand(360)
48+
@points = TrianglePoints.new
49+
3.times { @points << TPoint.new(Vec2D.new(rand(5..width - 5), rand(5..height - 5))) }
50+
background 0
51+
end
4852
end
4953

5054
Circles.new
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,3 @@
1-
### Dealing with processing coordinate system ###
2-
3-
For library see `library/circles/circles.rb`
4-
5-
If you want to create Math Sketches in processing, you need to deal with peculiar coordinate systems, where the Y-axis is inverted in theory you should be able to do.
6-
7-
```ruby
8-
scale(1, -1)
9-
translate(0, -height)
10-
```
11-
But that will mess up any text (plus you probably need to `push_matrix` and `pop_matrix`) so it is probably simpler to create a parallel coordinate system for the math, and translate that back to the screen (using the processing `map` function or in `propane` and `JRubyArt` use `map1d`).
12-
13-
We have done this in `circumcircle_sketch.rb` or just accept the processing coordinate system as we have with `basic_cirmcumcircle_sketch.rb` (it is much simpler).
14-
15-
### PVector limitations ###
16-
17-
PVector is a 3D vector, that is often used as a 2D vector, to my mind that is just plain wrong. If you evaluate the cross product of a 2D vector you get a float (you may see somewhere that a cross product does not exist for 2D vectors, but it can be useful). The cross product of PVector yields another PVector, so cannot be used in the calculation of the area of the triangle as defined by two vectors _cf_ Vec2D:-
18-
19-
```ruby
20-
a = Vec2D.new(100, 0)
21-
b = Vec2D.new(0, 100)
22-
23-
a.cross(b).abs == 10_000 # or twice the area of the triangle enclosed by a, b
24-
25-
```
26-
Further we can use the cross product in a test for collinearity
27-
28-
```ruby
29-
30-
# given 3 points in 2D space
31-
a = Vec2D.new(0, 0)
32-
b = Vec2D.new(100, 100)
33-
c = Vec2D.new(200, 200)
34-
35-
(a - b).cross(b - c) == 0 # the area of the triangle is zero, so a, b, c are collinear
36-
37-
```
38-
39-
Also because we were able to separate the logic, we were able to confidently re-factor the Barbara Almeida sketch to use Matrix math to determine the circumcenter
40-
411
### Matrix Math ###
422

433
For detailed workings see [Circumcircle at Mathworld Wolfram.com][circumcircle]
@@ -55,6 +15,3 @@ yo = -by / 2 * a
5515

5616

5717
[circumcircle]:http://mathworld.wolfram.com/Circumcircle.html
58-
59-
60-

processing_app/library/vecmath/vec2d/library/circles/lib/circumcircle.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ def initialize(points)
99

1010
def calculate
1111
@center = Vec2D.new(-(bx / am), -(by / am))
12-
@radius = center.dist(points[2]) # any point would do
12+
@radius = center.dist(points[2]) # points[2] = c
1313
end
1414

1515
private

processing_app/library/vecmath/vec2d/library/circles/lib/t_points.rb

+5-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
MAX_POINT = 3
44
# A collection of a maximum of 3 points in the processing world
55
# includes a collinearity test using Vec2D
6-
class TPoints
6+
class TrianglePoints
77
extend Forwardable
88
def_delegators(:@points, :each, :map, :size, :shift, :clear, :[])
99
include Enumerable
@@ -20,11 +20,12 @@ def <<(pt)
2020
end
2121

2222
def collinear?
23-
full? ? (vec[0] - vec[1]).cross(vec[1] - vec[2]).zero? : false
23+
full? ? (positions[0] - positions[1]).cross(positions[1] - positions[2]).zero? : false
2424
end
2525

26-
def vec
27-
points.map { |point| point.pos }
26+
# returns positions as an array of Vec2D
27+
def positions
28+
points.map(&:pos)
2829
end
2930

3031
def full?

processing_app/library/vecmath/vec2d/library/circles/lib/triangle_point.rb

+4-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
class TPoint
44
include Propane::Proxy
55
attr_reader :pos, :vel, :accel, :xbound, :ybound
6+
# attr_reader :width, :height # uncomment for testing
67

78
def initialize(position)
89
@pos = position
@@ -13,9 +14,11 @@ def initialize(position)
1314
end
1415

1516
def direction(acc)
17+
# direction of the acceleration is defined by the new angle
18+
@accel = acc
1619
# magnitude of the acceleration is proportional to the angle between
1720
# acceleration and velocity
18-
dif = accel.angle_between(vel)
21+
dif = acc.angle_between(vel)
1922
dif = map1d(dif, 0..PI, 0.1..0.001)
2023
@accel = acc * dif
2124
end

0 commit comments

Comments
 (0)