Class: Mittsu::Plane
- Inherits:
-
Object
- Object
- Mittsu::Plane
- Defined in:
- lib/mittsu/math/plane.rb
Instance Attribute Summary collapse
-
#constant ⇒ Object
Returns the value of attribute constant.
-
#normal ⇒ Object
Returns the value of attribute normal.
Instance Method Summary collapse
- #==(plane) ⇒ Object
- #apply_matrix4(matrix, normal_matrix = Mittsu::Matrix3.new.normal_matrix(matrix)) ⇒ Object
- #clone ⇒ Object
- #coplanar_point(target = Mittsu::Vector3.new) ⇒ Object
- #copy(plane) ⇒ Object
- #distance_to_point(point) ⇒ Object
- #distance_to_sphere(sphere) ⇒ Object
-
#initialize(normal = Mittsu::Vector3.new(1, 0, 0), constant = 0.0) ⇒ Plane
constructor
A new instance of Plane.
- #intersect_line(line, target = Mittsu::Vector3.new) ⇒ Object
- #intersection_line?(line) ⇒ Boolean
- #negate ⇒ Object
- #normalize ⇒ Object
- #ortho_point(point, target = Mittsu::Vector3.new) ⇒ Object
- #project_point(point, target = Mittsu::Vector3.new) ⇒ Object
- #set(normal, constant) ⇒ Object
- #set_components(x, y, z, w) ⇒ Object
- #set_from_coplanar_points(a, b, c) ⇒ Object
- #set_from_normal_and_coplanar_point(normal, point) ⇒ Object
- #translate(offset) ⇒ Object
Constructor Details
Instance Attribute Details
#constant ⇒ Object
Returns the value of attribute constant.
5 6 7 |
# File 'lib/mittsu/math/plane.rb', line 5 def constant @constant end |
#normal ⇒ Object
Returns the value of attribute normal.
5 6 7 |
# File 'lib/mittsu/math/plane.rb', line 5 def normal @normal end |
Instance Method Details
#==(plane) ⇒ Object
120 121 122 |
# File 'lib/mittsu/math/plane.rb', line 120 def ==(plane) plane.normal == @normal && plane.constant == @constant end |
#apply_matrix4(matrix, normal_matrix = Mittsu::Matrix3.new.normal_matrix(matrix)) ⇒ Object
103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/mittsu/math/plane.rb', line 103 def apply_matrix4(matrix, normal_matrix = Mittsu::Matrix3.new.normal_matrix(matrix)) v1 = Mittsu::Vector3.new v2 = Mittsu::Vector3.new # compute new normal based on theory here: # http:#www.songho.ca/opengl/gl_normaltransform.html new_normal = v1.copy(@normal).apply_matrix3(normal_matrix) new_coplanar_point = self.coplanar_point(v2) new_coplanar_point.apply_matrix4(matrix) self.set_from_normal_and_coplanar_point(new_normal, new_coplanar_point) self end |
#clone ⇒ Object
124 125 126 |
# File 'lib/mittsu/math/plane.rb', line 124 def clone Mittsu::Plane.new.copy(self) end |
#coplanar_point(target = Mittsu::Vector3.new) ⇒ Object
99 100 101 |
# File 'lib/mittsu/math/plane.rb', line 99 def coplanar_point(target = Mittsu::Vector3.new) target.copy(@normal).multiply_scalar(- @constant) end |
#copy(plane) ⇒ Object
38 39 40 41 42 |
# File 'lib/mittsu/math/plane.rb', line 38 def copy(plane) @normal.copy(plane.normal) @constant = plane.constant self end |
#distance_to_point(point) ⇒ Object
58 59 60 |
# File 'lib/mittsu/math/plane.rb', line 58 def distance_to_point(point) @normal.dot(point) + @constant end |
#distance_to_sphere(sphere) ⇒ Object
62 63 64 |
# File 'lib/mittsu/math/plane.rb', line 62 def distance_to_sphere(sphere) self.distance_to_point(sphere.center) - sphere.radius end |
#intersect_line(line, target = Mittsu::Vector3.new) ⇒ Object
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/mittsu/math/plane.rb', line 82 def intersect_line(line, target = Mittsu::Vector3.new) v1 = Mittsu::Vector3.new direction = line.delta(v1) denominator = @normal.dot(direction) if denominator.zero? # line is coplanar, return origin if self.distance_to_point(line.start_point).zero? return target.copy(line.start_point) end # Unsure if this is the correct method to handle this case. return nil end t = -(line.start_point.dot(@normal) + @constant) / denominator return nil if t < 0 || t > 1 target.copy(direction).multiply_scalar(t).add(line.start_point) end |
#intersection_line?(line) ⇒ Boolean
75 76 77 78 79 80 |
# File 'lib/mittsu/math/plane.rb', line 75 def intersection_line?(line) # Note: self tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it. start_sign = self.distance_to_point(line.start_point) end_sign = self.distance_to_point(line.end_point) (start_sign < 0 && end_sign > 0) || (end_sign < 0 && start_sign > 0) end |
#negate ⇒ Object
52 53 54 55 56 |
# File 'lib/mittsu/math/plane.rb', line 52 def negate @constant *= -1.0 @normal.negate self end |
#normalize ⇒ Object
44 45 46 47 48 49 50 |
# File 'lib/mittsu/math/plane.rb', line 44 def normalize # Note: will lead to a divide by zero if the plane is invalid. inverse_normal_length = 1.0 / @normal.length @normal.multiply_scalar(inverse_normal_length) @constant *= inverse_normal_length self end |
#ortho_point(point, target = Mittsu::Vector3.new) ⇒ Object
70 71 72 73 |
# File 'lib/mittsu/math/plane.rb', line 70 def ortho_point(point, target = Mittsu::Vector3.new) perpendicular_magnitude = self.distance_to_point(point) target.copy(@normal).multiply_scalar(perpendicular_magnitude) end |
#project_point(point, target = Mittsu::Vector3.new) ⇒ Object
66 67 68 |
# File 'lib/mittsu/math/plane.rb', line 66 def project_point(point, target = Mittsu::Vector3.new) self.ortho_point(point, target).sub(point).negate end |
#set(normal, constant) ⇒ Object
11 12 13 14 15 |
# File 'lib/mittsu/math/plane.rb', line 11 def set(normal, constant) @normal.copy(normal) @constant = constant.to_f self end |
#set_components(x, y, z, w) ⇒ Object
17 18 19 20 21 |
# File 'lib/mittsu/math/plane.rb', line 17 def set_components(x, y, z, w) @normal.set(x, y, z) @constant = w.to_f self end |
#set_from_coplanar_points(a, b, c) ⇒ Object
29 30 31 32 33 34 35 36 |
# File 'lib/mittsu/math/plane.rb', line 29 def set_from_coplanar_points(a, b, c) v1 = Mittsu::Vector3.new v2 = Mittsu::Vector3.new normal = v1.sub_vectors(c, b).cross(v2.sub_vectors(a, b)).normalize # Q: should an error be thrown if normal is zero (e.g. degenerate plane)? self.set_from_normal_and_coplanar_point(normal, a) self end |
#set_from_normal_and_coplanar_point(normal, point) ⇒ Object
23 24 25 26 27 |
# File 'lib/mittsu/math/plane.rb', line 23 def set_from_normal_and_coplanar_point(normal, point) @normal.copy(normal) @constant = -point.dot(@normal) # must be @normal, not normal, as @normal is normalized self end |
#translate(offset) ⇒ Object
115 116 117 118 |
# File 'lib/mittsu/math/plane.rb', line 115 def translate(offset) @constant = @constant - offset.dot(@normal) self end |