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

Instance Method Summary collapse

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

Instance Method Details

#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

#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