Class: SFML::Vector3

Inherits:
Object
  • Object
show all
Defined in:
lib/sfml/system/vector3.rb

Overview

3D vector with float components. Mirrors Vector2's surface — same arithmetic, same coerce trick for 2 * v, same pattern-match support. Used by the 3D-audio API (Sound#position, Listener, …) and as a back-end for Image size hints.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(x = 0, y = 0, z = 0) ⇒ Vector3

Returns a new instance of Vector3.



16
17
18
19
20
21
# File 'lib/sfml/system/vector3.rb', line 16

def initialize(x = 0, y = 0, z = 0)
  @x = x
  @y = y
  @z = z
  freeze
end

Instance Attribute Details

#x ⇒ Object (readonly)

The X coordinate, Y coordinate, Z coordinate components.



8
9
10
# File 'lib/sfml/system/vector3.rb', line 8

def x
  @x
end

#y ⇒ Object (readonly)

The X coordinate, Y coordinate, Z coordinate components.



8
9
10
# File 'lib/sfml/system/vector3.rb', line 8

def y
  @y
end

#z ⇒ Object (readonly)

The X coordinate, Y coordinate, Z coordinate components.



8
9
10
# File 'lib/sfml/system/vector3.rb', line 8

def z
  @z
end

Class Method Details

.[](x, y, z) ⇒ Object

Compact constructor: Vector3[1, 2, 3].



11
# File 'lib/sfml/system/vector3.rb', line 11

def self.[](x, y, z) = new(x, y, z)

.from_native(struct) ⇒ Object

Returns the self.



153
154
155
# File 'lib/sfml/system/vector3.rb', line 153

def self.from_native(struct) # :nodoc:
  new(struct[:x], struct[:y], struct[:z])
end

.zero ⇒ Object

The (0, 0, 0) vector.



14
# File 'lib/sfml/system/vector3.rb', line 14

def self.zero = new(0, 0, 0)

Instance Method Details

#*(scalar) ⇒ Object

Multiply every component by scalar.



28
29
# File 'lib/sfml/system/vector3.rb', line 28

def *(scalar) = Vector3.new(@x * scalar, @y * scalar, @z * scalar)
# Divide every component by `scalar` (promotes to Float).

#+(other) ⇒ Object

Component-wise addition.



24
25
# File 'lib/sfml/system/vector3.rb', line 24

def +(other) = Vector3.new(@x + other.x, @y + other.y, @z + other.z)
# Component-wise subtraction.

#-(other) ⇒ Object

Component-wise subtraction.



26
27
# File 'lib/sfml/system/vector3.rb', line 26

def -(other) = Vector3.new(@x - other.x, @y - other.y, @z - other.z)
# Multiply every component by `scalar`.

#-@ ⇒ Object

Negate every component.



32
# File 'lib/sfml/system/vector3.rb', line 32

def -@ = Vector3.new(-@x, -@y, -@z)

#/(scalar) ⇒ Object

Divide every component by scalar (promotes to Float).



30
31
# File 'lib/sfml/system/vector3.rb', line 30

def /(scalar) = Vector3.new(@x / scalar.to_f, @y / scalar.to_f, @z / scalar.to_f)
# Negate every component.

#==(other) ⇒ Object Also known as: eql?

Value equality — all three components must match.



35
36
37
# File 'lib/sfml/system/vector3.rb', line 35

def ==(other)
  other.is_a?(Vector3) && @x == other.x && @y == other.y && @z == other.z
end

#abs ⇒ Object

Per-component absolute value.



131
# File 'lib/sfml/system/vector3.rb', line 131

def abs   = Vector3.new(@x.abs, @y.abs, @z.abs)

#angle_between(other) ⇒ Object

Angle between two direction vectors, in radians. Both vectors should be non-zero — returns 0 for either side zero.



89
90
91
92
93
94
95
96
# File 'lib/sfml/system/vector3.rb', line 89

def angle_between(other)
  o  = _coerce(other)
  la = length
  lo = o.length
  return 0.0 if la.zero? || lo.zero?
  cos = (dot(o) / (la * lo)).clamp(-1.0, 1.0)
  Math.acos(cos)
end

#clamp_length(min_len = nil, max_len) ⇒ Object

Clamp the magnitude into [min_len, max_len]. Either bound may be nil to leave that side unclamped.



115
116
117
118
119
120
121
122
123
124
125
# File 'lib/sfml/system/vector3.rb', line 115

def clamp_length(min_len = nil, max_len)
  len = length
  return self if len.zero?
  target =
    if    max_len && len > max_len then max_len
    elsif min_len && len < min_len then min_len
    else len
    end
  return self if target == len
  self * (target / len)
end

#coerce(other) ⇒ Object

Lets Ruby evaluate 2 * vec as vec * 2.

Raises:

  • (TypeError)


70
71
72
73
# File 'lib/sfml/system/vector3.rb', line 70

def coerce(other)
  raise TypeError, "Vector3 cannot coerce #{other.class}" unless other.is_a?(Numeric)
  [self, other]
end

#cross(other) ⇒ Object

3D cross product (vector perpendicular to both).



61
62
63
64
65
66
67
# File 'lib/sfml/system/vector3.rb', line 61

def cross(other)
  Vector3.new(
    (@y * other.z) - (@z * other.y),
    (@z * other.x) - (@x * other.z),
    (@x * other.y) - (@y * other.x)
  )
end

#deconstruct ⇒ Object

Pattern-match support for in [x, y, z].



143
# File 'lib/sfml/system/vector3.rb', line 143

def deconstruct = [@x, @y, @z]

#deconstruct_keys(_keys) ⇒ Object

Pattern-match support for in {x:, y:, z:}.



146
# File 'lib/sfml/system/vector3.rb', line 146

def deconstruct_keys(_keys) = { x: @x, y: @y, z: @z }

#distance(other) ⇒ Object

Euclidean distance between two points — accepts Vector3 or [x, y, z].



77
78
# File 'lib/sfml/system/vector3.rb', line 77

def distance(other)    = (self - _coerce(other)).length
# Squared distance (skip the square root) for comparisons.

#distance_sq(other) ⇒ Object

Squared distance (skip the square root) for comparisons.



79
# File 'lib/sfml/system/vector3.rb', line 79

def distance_sq(other) = (self - _coerce(other)).length_sq

#dot(other) ⇒ Object

Scalar dot product.



58
# File 'lib/sfml/system/vector3.rb', line 58

def dot(other) = (@x * other.x) + (@y * other.y) + (@z * other.z)

#hash ⇒ Object

Hash key support.



40
# File 'lib/sfml/system/vector3.rb', line 40

def hash = [@x, @y, @z].hash

#length ⇒ Object

Euclidean length √(x² + y² + z²). Prefer length_sq for comparisons to skip the square root.



44
45
46
# File 'lib/sfml/system/vector3.rb', line 44

def length    = Math.sqrt(length_sq)
# Squared length (x² + y² + z²) — faster than `length` when you
# only need to compare magnitudes.

#length_sq ⇒ Object

Squared length (x² + y² + z²) — faster than length when you only need to compare magnitudes.



47
# File 'lib/sfml/system/vector3.rb', line 47

def length_sq = (@x * @x) + (@y * @y) + (@z * @z)

#lerp(other, t) ⇒ Object

Linear interpolation toward other at parameter t ∈ [0, 1].



82
83
84
85
# File 'lib/sfml/system/vector3.rb', line 82

def lerp(other, t)
  o = _coerce(other)
  Vector3.new(@x + (o.x - @x) * t, @y + (o.y - @y) * t, @z + (o.z - @z) * t)
end

#normalize ⇒ Object

Unit vector in the same direction. Zero vector returns itself unchanged.



51
52
53
54
55
# File 'lib/sfml/system/vector3.rb', line 51

def normalize
  len = length
  return Vector3.zero if len.zero?
  self / len
end

#project_on(other) ⇒ Object

Vector projection of self onto other.



99
100
101
102
103
104
# File 'lib/sfml/system/vector3.rb', line 99

def project_on(other)
  o = _coerce(other)
  d = o.length_sq
  return Vector3.zero if d.zero?
  o * (dot(o) / d)
end

#reflect(normal) ⇒ Object

Reflect this vector across the plane defined by normal. normal should be unit-length.



108
109
110
111
# File 'lib/sfml/system/vector3.rb', line 108

def reflect(normal)
  n = _coerce(normal)
  self - (n * (2 * dot(n)))
end

#to_a ⇒ Object

As [x, y, z].



137
# File 'lib/sfml/system/vector3.rb', line 137

def to_a = [@x, @y, @z]

#to_h ⇒ Object

As {x:, y:, z:}.



140
# File 'lib/sfml/system/vector3.rb', line 140

def to_h = { x: @x, y: @y, z: @z }

#to_native_f ⇒ Object

Returns the to native f.



158
159
160
# File 'lib/sfml/system/vector3.rb', line 158

def to_native_f # :nodoc:
  C::System::Vector3f.new.tap { |v| v[:x] = @x; v[:y] = @y; v[:z] = @z }
end

#to_s ⇒ Object Also known as: inspect

String representation for debugging.



149
# File 'lib/sfml/system/vector3.rb', line 149

def to_s = "Vector3(#{@x}, #{@y}, #{@z})"

#to_v2 ⇒ Object

Drop the z component → Vector2.



134
# File 'lib/sfml/system/vector3.rb', line 134

def to_v2 = Vector2.new(@x, @y)

#zero? ⇒ Boolean

true iff all three components are zero.

Returns:

  • (Boolean)


128
# File 'lib/sfml/system/vector3.rb', line 128

def zero? = @x.zero? && @y.zero? && @z.zero?