Class: RTanque::Point

Inherits:
Struct
  • Object
show all
Defined in:
lib/rtanque/point.rb

Overview

A Point represents an [x, y] coordinate pair in the Arena

Usage

@arena = RTanque::Arena.new(100, 100)
# => #<struct RTanque::Arena width=100, height=100>

@point_one = RTanque::Point.new(0, 1, @arena)
# => #<struct RTanque::Point x=0, y=1, arena=#<struct RTanque::Arena width=100, height=100>>

@point_one.on_top_wall?
# => false

@point_one.on_bottom_wall?
# => false

@point_one.on_right_wall?
# => false

@point_one.on_left_wall?
# => true

@point_one.on_wall?
# => true

@point_two = RTanque::Point.new(100, 1, @arena)
# => #<struct RTanque::Point x=100, y=1, arena=#<struct RTanque::Arena width=100, height=100>>

@point_two.within_radius?(@point_one, 10)
# => false

@point_two.within_radius?(@point_one, 100)
# => true

@point_two.distance(@point_one)
# => 100.0

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args, &block) ⇒ Point

Returns a new instance of Point.



66
67
68
69
70
# File 'lib/rtanque/point.rb', line 66

def initialize(*args, &block)
  super
  block.call(self) if block
  self.freeze
end

Instance Attribute Details

#arenaRTanque::Arena (readonly)

Returns the current value of arena.

Returns:



65
66
67
# File 'lib/rtanque/point.rb', line 65

def arena
  @arena
end

#xNumeric (readonly)

horizontal position (left edge is 0)

Returns:

  • (Numeric)

    the current value of x



65
66
67
# File 'lib/rtanque/point.rb', line 65

def x
  @x
end

#yNumeric (readonly)

vertical position (bottom edge is 0)

Returns:

  • (Numeric)

    the current value of y



65
66
67
# File 'lib/rtanque/point.rb', line 65

def y
  @y
end

Class Method Details

.distance(a, b) ⇒ Object



76
77
78
# File 'lib/rtanque/point.rb', line 76

def self.distance(a, b)
  Math.hypot(a.x - b.x, a.y - b.y)
end

.rand(arena) ⇒ Object



72
73
74
# File 'lib/rtanque/point.rb', line 72

def self.rand(arena)
  self.new(Kernel.rand(arena.width), Kernel.rand(arena.height), arena)
end

Instance Method Details

#==(other_point) ⇒ Object



80
81
82
# File 'lib/rtanque/point.rb', line 80

def ==(other_point)
  self.x == other_point.x && self.y == other_point.y
end

#bind_to_arenaObject



119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/rtanque/point.rb', line 119

def bind_to_arena
  if self.x < 0
    self.x = 0.0
  elsif self.x > self.arena.width
    self.x = self.arena.width.to_f
  end
  if self.y < 0
    self.y = 0.0
  elsif self.y > self.arena.height
    self.y = self.arena.height.to_f
  end
end

#distance(other_point) ⇒ Float

Parameters:

Returns:

  • (Float)


65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/rtanque/point.rb', line 65

Point = Struct.new(:x, :y, :arena) do
  def initialize(*args, &block)
    super
    block.call(self) if block
    self.freeze
  end

  def self.rand(arena)
    self.new(Kernel.rand(arena.width), Kernel.rand(arena.height), arena)
  end

  def self.distance(a, b)
    Math.hypot(a.x - b.x, a.y - b.y)
  end

  def ==(other_point)
    self.x == other_point.x && self.y == other_point.y
  end

  def within_radius?(other_point, radius)
    self.distance(other_point) <= radius
  end

  def on_top_wall?
    self.y >= self.arena.height
  end

  def on_bottom_wall?
    self.y <= 0
  end

  def on_left_wall?
    self.x <= 0
  end

  def on_right_wall?
    self.x >= self.arena.width
  end

  def on_wall?
    self.on_top_wall? || self.on_bottom_wall? || self.on_right_wall? || self.on_left_wall?
  end

  def outside_arena?
    self.y > self.arena.height || self.y < 0 || self.x > self.arena.width || self.x < 0
  end

  def move(heading, speed, bound_to_arena = true)
    # round to avoid floating point errors
    x = (self.x + (Math.sin(heading) * speed)).round(10)
    y = (self.y + (Math.cos(heading) * speed)).round(10)
    self.class.new(x, y, self.arena) { |point| point.bind_to_arena if bound_to_arena }
  end

  def bind_to_arena
    if self.x < 0
      self.x = 0.0
    elsif self.x > self.arena.width
      self.x = self.arena.width.to_f
    end
    if self.y < 0
      self.y = 0.0
    elsif self.y > self.arena.height
      self.y = self.arena.height.to_f
    end
  end

  def heading(other_point)
    Heading.new_between_points(self, other_point)
  end

  def distance(other_point)
    self.class.distance(self, other_point)
  end
end

#heading(other_point) ⇒ RTanque::Heading

Parameters:

Returns:



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/rtanque/point.rb', line 65

Point = Struct.new(:x, :y, :arena) do
  def initialize(*args, &block)
    super
    block.call(self) if block
    self.freeze
  end

  def self.rand(arena)
    self.new(Kernel.rand(arena.width), Kernel.rand(arena.height), arena)
  end

  def self.distance(a, b)
    Math.hypot(a.x - b.x, a.y - b.y)
  end

  def ==(other_point)
    self.x == other_point.x && self.y == other_point.y
  end

  def within_radius?(other_point, radius)
    self.distance(other_point) <= radius
  end

  def on_top_wall?
    self.y >= self.arena.height
  end

  def on_bottom_wall?
    self.y <= 0
  end

  def on_left_wall?
    self.x <= 0
  end

  def on_right_wall?
    self.x >= self.arena.width
  end

  def on_wall?
    self.on_top_wall? || self.on_bottom_wall? || self.on_right_wall? || self.on_left_wall?
  end

  def outside_arena?
    self.y > self.arena.height || self.y < 0 || self.x > self.arena.width || self.x < 0
  end

  def move(heading, speed, bound_to_arena = true)
    # round to avoid floating point errors
    x = (self.x + (Math.sin(heading) * speed)).round(10)
    y = (self.y + (Math.cos(heading) * speed)).round(10)
    self.class.new(x, y, self.arena) { |point| point.bind_to_arena if bound_to_arena }
  end

  def bind_to_arena
    if self.x < 0
      self.x = 0.0
    elsif self.x > self.arena.width
      self.x = self.arena.width.to_f
    end
    if self.y < 0
      self.y = 0.0
    elsif self.y > self.arena.height
      self.y = self.arena.height.to_f
    end
  end

  def heading(other_point)
    Heading.new_between_points(self, other_point)
  end

  def distance(other_point)
    self.class.distance(self, other_point)
  end
end

#move(heading, speed, bound_to_arena = true) ⇒ Object



112
113
114
115
116
117
# File 'lib/rtanque/point.rb', line 112

def move(heading, speed, bound_to_arena = true)
  # round to avoid floating point errors
  x = (self.x + (Math.sin(heading) * speed)).round(10)
  y = (self.y + (Math.cos(heading) * speed)).round(10)
  self.class.new(x, y, self.arena) { |point| point.bind_to_arena if bound_to_arena }
end

#on_bottom_wall?Boolean

Returns:

  • (Boolean)


65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/rtanque/point.rb', line 65

Point = Struct.new(:x, :y, :arena) do
  def initialize(*args, &block)
    super
    block.call(self) if block
    self.freeze
  end

  def self.rand(arena)
    self.new(Kernel.rand(arena.width), Kernel.rand(arena.height), arena)
  end

  def self.distance(a, b)
    Math.hypot(a.x - b.x, a.y - b.y)
  end

  def ==(other_point)
    self.x == other_point.x && self.y == other_point.y
  end

  def within_radius?(other_point, radius)
    self.distance(other_point) <= radius
  end

  def on_top_wall?
    self.y >= self.arena.height
  end

  def on_bottom_wall?
    self.y <= 0
  end

  def on_left_wall?
    self.x <= 0
  end

  def on_right_wall?
    self.x >= self.arena.width
  end

  def on_wall?
    self.on_top_wall? || self.on_bottom_wall? || self.on_right_wall? || self.on_left_wall?
  end

  def outside_arena?
    self.y > self.arena.height || self.y < 0 || self.x > self.arena.width || self.x < 0
  end

  def move(heading, speed, bound_to_arena = true)
    # round to avoid floating point errors
    x = (self.x + (Math.sin(heading) * speed)).round(10)
    y = (self.y + (Math.cos(heading) * speed)).round(10)
    self.class.new(x, y, self.arena) { |point| point.bind_to_arena if bound_to_arena }
  end

  def bind_to_arena
    if self.x < 0
      self.x = 0.0
    elsif self.x > self.arena.width
      self.x = self.arena.width.to_f
    end
    if self.y < 0
      self.y = 0.0
    elsif self.y > self.arena.height
      self.y = self.arena.height.to_f
    end
  end

  def heading(other_point)
    Heading.new_between_points(self, other_point)
  end

  def distance(other_point)
    self.class.distance(self, other_point)
  end
end

#on_left_wall?Boolean

Returns:

  • (Boolean)


65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/rtanque/point.rb', line 65

Point = Struct.new(:x, :y, :arena) do
  def initialize(*args, &block)
    super
    block.call(self) if block
    self.freeze
  end

  def self.rand(arena)
    self.new(Kernel.rand(arena.width), Kernel.rand(arena.height), arena)
  end

  def self.distance(a, b)
    Math.hypot(a.x - b.x, a.y - b.y)
  end

  def ==(other_point)
    self.x == other_point.x && self.y == other_point.y
  end

  def within_radius?(other_point, radius)
    self.distance(other_point) <= radius
  end

  def on_top_wall?
    self.y >= self.arena.height
  end

  def on_bottom_wall?
    self.y <= 0
  end

  def on_left_wall?
    self.x <= 0
  end

  def on_right_wall?
    self.x >= self.arena.width
  end

  def on_wall?
    self.on_top_wall? || self.on_bottom_wall? || self.on_right_wall? || self.on_left_wall?
  end

  def outside_arena?
    self.y > self.arena.height || self.y < 0 || self.x > self.arena.width || self.x < 0
  end

  def move(heading, speed, bound_to_arena = true)
    # round to avoid floating point errors
    x = (self.x + (Math.sin(heading) * speed)).round(10)
    y = (self.y + (Math.cos(heading) * speed)).round(10)
    self.class.new(x, y, self.arena) { |point| point.bind_to_arena if bound_to_arena }
  end

  def bind_to_arena
    if self.x < 0
      self.x = 0.0
    elsif self.x > self.arena.width
      self.x = self.arena.width.to_f
    end
    if self.y < 0
      self.y = 0.0
    elsif self.y > self.arena.height
      self.y = self.arena.height.to_f
    end
  end

  def heading(other_point)
    Heading.new_between_points(self, other_point)
  end

  def distance(other_point)
    self.class.distance(self, other_point)
  end
end

#on_right_wall?Boolean

Returns:

  • (Boolean)


65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/rtanque/point.rb', line 65

Point = Struct.new(:x, :y, :arena) do
  def initialize(*args, &block)
    super
    block.call(self) if block
    self.freeze
  end

  def self.rand(arena)
    self.new(Kernel.rand(arena.width), Kernel.rand(arena.height), arena)
  end

  def self.distance(a, b)
    Math.hypot(a.x - b.x, a.y - b.y)
  end

  def ==(other_point)
    self.x == other_point.x && self.y == other_point.y
  end

  def within_radius?(other_point, radius)
    self.distance(other_point) <= radius
  end

  def on_top_wall?
    self.y >= self.arena.height
  end

  def on_bottom_wall?
    self.y <= 0
  end

  def on_left_wall?
    self.x <= 0
  end

  def on_right_wall?
    self.x >= self.arena.width
  end

  def on_wall?
    self.on_top_wall? || self.on_bottom_wall? || self.on_right_wall? || self.on_left_wall?
  end

  def outside_arena?
    self.y > self.arena.height || self.y < 0 || self.x > self.arena.width || self.x < 0
  end

  def move(heading, speed, bound_to_arena = true)
    # round to avoid floating point errors
    x = (self.x + (Math.sin(heading) * speed)).round(10)
    y = (self.y + (Math.cos(heading) * speed)).round(10)
    self.class.new(x, y, self.arena) { |point| point.bind_to_arena if bound_to_arena }
  end

  def bind_to_arena
    if self.x < 0
      self.x = 0.0
    elsif self.x > self.arena.width
      self.x = self.arena.width.to_f
    end
    if self.y < 0
      self.y = 0.0
    elsif self.y > self.arena.height
      self.y = self.arena.height.to_f
    end
  end

  def heading(other_point)
    Heading.new_between_points(self, other_point)
  end

  def distance(other_point)
    self.class.distance(self, other_point)
  end
end

#on_top_wall?Boolean

Returns:

  • (Boolean)


65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/rtanque/point.rb', line 65

Point = Struct.new(:x, :y, :arena) do
  def initialize(*args, &block)
    super
    block.call(self) if block
    self.freeze
  end

  def self.rand(arena)
    self.new(Kernel.rand(arena.width), Kernel.rand(arena.height), arena)
  end

  def self.distance(a, b)
    Math.hypot(a.x - b.x, a.y - b.y)
  end

  def ==(other_point)
    self.x == other_point.x && self.y == other_point.y
  end

  def within_radius?(other_point, radius)
    self.distance(other_point) <= radius
  end

  def on_top_wall?
    self.y >= self.arena.height
  end

  def on_bottom_wall?
    self.y <= 0
  end

  def on_left_wall?
    self.x <= 0
  end

  def on_right_wall?
    self.x >= self.arena.width
  end

  def on_wall?
    self.on_top_wall? || self.on_bottom_wall? || self.on_right_wall? || self.on_left_wall?
  end

  def outside_arena?
    self.y > self.arena.height || self.y < 0 || self.x > self.arena.width || self.x < 0
  end

  def move(heading, speed, bound_to_arena = true)
    # round to avoid floating point errors
    x = (self.x + (Math.sin(heading) * speed)).round(10)
    y = (self.y + (Math.cos(heading) * speed)).round(10)
    self.class.new(x, y, self.arena) { |point| point.bind_to_arena if bound_to_arena }
  end

  def bind_to_arena
    if self.x < 0
      self.x = 0.0
    elsif self.x > self.arena.width
      self.x = self.arena.width.to_f
    end
    if self.y < 0
      self.y = 0.0
    elsif self.y > self.arena.height
      self.y = self.arena.height.to_f
    end
  end

  def heading(other_point)
    Heading.new_between_points(self, other_point)
  end

  def distance(other_point)
    self.class.distance(self, other_point)
  end
end

#on_wall?Boolean

True if on any wall

Returns:

  • (Boolean)


65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/rtanque/point.rb', line 65

Point = Struct.new(:x, :y, :arena) do
  def initialize(*args, &block)
    super
    block.call(self) if block
    self.freeze
  end

  def self.rand(arena)
    self.new(Kernel.rand(arena.width), Kernel.rand(arena.height), arena)
  end

  def self.distance(a, b)
    Math.hypot(a.x - b.x, a.y - b.y)
  end

  def ==(other_point)
    self.x == other_point.x && self.y == other_point.y
  end

  def within_radius?(other_point, radius)
    self.distance(other_point) <= radius
  end

  def on_top_wall?
    self.y >= self.arena.height
  end

  def on_bottom_wall?
    self.y <= 0
  end

  def on_left_wall?
    self.x <= 0
  end

  def on_right_wall?
    self.x >= self.arena.width
  end

  def on_wall?
    self.on_top_wall? || self.on_bottom_wall? || self.on_right_wall? || self.on_left_wall?
  end

  def outside_arena?
    self.y > self.arena.height || self.y < 0 || self.x > self.arena.width || self.x < 0
  end

  def move(heading, speed, bound_to_arena = true)
    # round to avoid floating point errors
    x = (self.x + (Math.sin(heading) * speed)).round(10)
    y = (self.y + (Math.cos(heading) * speed)).round(10)
    self.class.new(x, y, self.arena) { |point| point.bind_to_arena if bound_to_arena }
  end

  def bind_to_arena
    if self.x < 0
      self.x = 0.0
    elsif self.x > self.arena.width
      self.x = self.arena.width.to_f
    end
    if self.y < 0
      self.y = 0.0
    elsif self.y > self.arena.height
      self.y = self.arena.height.to_f
    end
  end

  def heading(other_point)
    Heading.new_between_points(self, other_point)
  end

  def distance(other_point)
    self.class.distance(self, other_point)
  end
end

#outside_arena?Boolean

Returns:

  • (Boolean)


108
109
110
# File 'lib/rtanque/point.rb', line 108

def outside_arena?
  self.y > self.arena.height || self.y < 0 || self.x > self.arena.width || self.x < 0
end

#within_radius?(other_point, radius) ⇒ Boolean

Returns:

  • (Boolean)


84
85
86
# File 'lib/rtanque/point.rb', line 84

def within_radius?(other_point, radius)
  self.distance(other_point) <= radius
end