Module: Sc2::Position

Included in:
Api::Point, Api::Point2D, Api::PointI, Api::PowerSourceExtension, Api::Size2DI
Defined in:
lib/sc2ai/protocol/extensions/position.rb

Overview

A unified construct that tames Api::* messages which contain location data Items which are of type Sc2::Position will have #x and #y property at the least.

Constant Summary collapse

TOLERANCE =

Tolerance for floating-point comparisons.

1e-9

Instance Method Summary collapse

Instance Method Details

#==(other) ⇒ Boolean

Loose equality matches on floats x and y. We never check z-axis, because the map is single-level. TODO: We should almost certainly introduce TOLERANCE here, but verify it’s cost first.

Parameters:

Returns:

  • (Boolean)


23
24
25
26
27
28
29
# File 'lib/sc2ai/protocol/extensions/position.rb', line 23

def ==(other)
  if other.is_a? Position
    x == other.x && y == other.y
  else
    false
  end
end

#add(other) ⇒ Api::Point2D Also known as: +

A new point representing the sum of this point and the other point.

Parameters:

  • other (Api::Point2D, Numeric)

    The other point/number to add.

Returns:



34
35
36
37
38
39
40
# File 'lib/sc2ai/protocol/extensions/position.rb', line 34

def add(other)
  if other.is_a? Numeric
    Api::Point2D[x + other, y + other]
  else
    Api::Point2D[x + other.x, y + other.y]
  end
end

#angle_to(other) ⇒ Float

The angle between this vector and the other vector, in radians.

Parameters:

  • other (Api::Point2D)

    The other vector to calculate the angle to.

Returns:

  • (Float)


135
136
137
# File 'lib/sc2ai/protocol/extensions/position.rb', line 135

def angle_to(other)
  Math.acos(dot(other) / (magnitude * other.magnitude))
end

#away_from(other, distance) ⇒ Api::Point2D

Moves in direction away from the other point by distance

Parameters:

  • other (Api::Point2D)

    The target point to move away from

  • distance (Float)

    The distance to move.

Returns:



214
215
216
# File 'lib/sc2ai/protocol/extensions/position.rb', line 214

def away_from(other, distance)
  towards(other, -distance)
end

#cross_product(other) ⇒ Float

The cross product of this vector and the other vector.

Parameters:

  • other (Api::Point2D)

    The other vector to calculate the cross product with.

Returns:

  • (Float)


128
129
130
# File 'lib/sc2ai/protocol/extensions/position.rb', line 128

def cross_product(other)
  x * other.y - y * other.x
end

#distance_squared_to(other) ⇒ Float

The squared distance between this point and the other point.

Parameters:

  • other (Api::Point2D)

    The other point to calculate the squared distance to.

Returns:

  • (Float)


171
172
173
174
175
176
# File 'lib/sc2ai/protocol/extensions/position.rb', line 171

def distance_squared_to(other)
  if other.nil? || other == self
    return 0.0
  end
  (x - other.x) * (y - other.y)
end

#distance_to(other) ⇒ Float

Calculates the distance between self and other

Parameters:

Returns:

  • (Float)


161
162
163
164
165
166
# File 'lib/sc2ai/protocol/extensions/position.rb', line 161

def distance_to(other)
  if other.nil? || other == self
    return 0.0
  end
  Math.hypot(self.x - other.x, self.y - other.y)
end

#distance_to_circle(center, radius) ⇒ Float

The distance from this point to the circle.

Parameters:

  • center (Api::Point2D)

    The center of the circle.

  • radius (Float)

    The radius of the circle.

Returns:

  • (Float)


190
191
192
193
194
195
196
197
# File 'lib/sc2ai/protocol/extensions/position.rb', line 190

def distance_to_circle(center, radius)
  distance_to_center = distance_to(center)
  if distance_to_center <= radius
    0.0 # Point is inside the circle
  else
    distance_to_center - radius
  end
end

#distance_to_coordinate(x:, y:) ⇒ Float

Distance between this point and coordinate of x and y

Parameters:

  • x (Float, Integer)
  • y (Float, Integer)

Returns:

  • (Float)


182
183
184
# File 'lib/sc2ai/protocol/extensions/position.rb', line 182

def distance_to_coordinate(x:, y:)
  Math.hypot(self.x - x, self.y - y)
end

#divide(scalar) ⇒ Api::Point2D Also known as: /

Returns A new point representing this point divided by the scalar.

Parameters:

  • scalar (Float)

    The scalar to divide by.

Returns:

  • (Api::Point2D)

    A new point representing this point divided by the scalar.

Raises:

  • (ZeroDivisionError)

    if the scalar is zero.



67
68
69
70
# File 'lib/sc2ai/protocol/extensions/position.rb', line 67

def divide(scalar)
  raise ZeroDivisionError if scalar.zero?
  Api::Point2D[x / scalar, y / scalar]
end

#dot(other) ⇒ Float

The dot product of this vector and the other vector.

Parameters:

  • other (Api::Point2D)

    The other vector to calculate the dot product with.

Returns:

  • (Float)


121
122
123
# File 'lib/sc2ai/protocol/extensions/position.rb', line 121

def dot(other)
  x * other.x + y * other.y
end

#lerp(other, scale) ⇒ Api::Point2D

Linear interpolation between this point and another for scale Finds a point on a line between two points at % along the way. 0.0 returns self, 1.0 returns other, 0.5 is halfway.

Parameters:

  • other (Sc2::Position)
  • scale (Float)

    a value between 0.0..1.0

Returns:



152
153
154
# File 'lib/sc2ai/protocol/extensions/position.rb', line 152

def lerp(other, scale)
  Api::Point2D[x + (other.x - x) * scale, y + (other.y - y) * scale]
end

#magnitudeFloat

For vector returns the magnitude, synonymous with Math.hypot

Returns:

  • (Float)


114
115
116
# File 'lib/sc2ai/protocol/extensions/position.rb', line 114

def magnitude
  Math.hypot(x, y)
end

#multiply(scalar) ⇒ Api::Point2D Also known as: *

Returns this point multiplied by the scalar

Parameters:

  • scalar (Float)

    The scalar to multiply by.

Returns:



58
59
60
# File 'lib/sc2ai/protocol/extensions/position.rb', line 58

def multiply(scalar)
  Api::Point2D[x * scalar, y * scalar]
end

#normalizeApi::Point2D

A new point representing the normalized version of this vector (unit length).

Returns:



141
142
143
# File 'lib/sc2ai/protocol/extensions/position.rb', line 141

def normalize
  divide(magnitude)
end

#offset(x = 0, y = 0) ⇒ Sc2::Position

Creates a new point with x and y which is offset

Parameters:

  • x (Float, Integer) (defaults to: 0)
  • y (Float, Integer) (defaults to: 0)

Returns:



96
97
98
# File 'lib/sc2ai/protocol/extensions/position.rb', line 96

def offset(x = 0, y = 0)
  dup.offset!(x, y)
end

#offset!(x = 0, y = 0) ⇒ Sc2::Position

Changes this point’s x and y by the supplied offset

Parameters:

  • x (Float, Integer) (defaults to: 0)
  • y (Float, Integer) (defaults to: 0)

Returns:



104
105
106
107
108
# File 'lib/sc2ai/protocol/extensions/position.rb', line 104

def offset!(x = 0, y = 0)
  self.x += x
  self.y += y
  self
end

#posSc2::Position

Returns self. If you’re ever unsure if you have a Unit or Position in hand, this method allows safely calling ‘unknown_target.pos` to return a position.

Examples:

target.pos

Returns:



14
# File 'lib/sc2ai/protocol/extensions/position.rb', line 14

def pos = self

#random_offset(offset) ⇒ Sc2::Position

Randomly adjusts both x and y by a range of: -offset..offset

Parameters:

  • offset (Float)

Returns:



77
78
79
# File 'lib/sc2ai/protocol/extensions/position.rb', line 77

def random_offset(offset)
  dup.random_offset!(offset)
end

#random_offset!(offset) ⇒ Sc2::Position

Randomly change this point’s x and y by the supplied offset. i.e. offset=2 can adjust x and y by any number in range -2..2

Parameters:

  • offset (Float)

Returns:



85
86
87
88
89
90
# File 'lib/sc2ai/protocol/extensions/position.rb', line 85

def random_offset!(offset)
  offset = offset.to_f.abs
  range = -offset..offset
  offset!(rand(range), rand(range))
  self
end

#subtract(other) ⇒ Api::Point2D Also known as: -

Returns a new point representing the difference between this point and the other point/number.

Parameters:

Returns:



46
47
48
49
50
51
52
# File 'lib/sc2ai/protocol/extensions/position.rb', line 46

def subtract(other)
  if other.is_a? Numeric
    Api::Point2D[x - other, y - other]
  else
    Api::Point2D[x - other.x, y - other.y]
  end
end

#to_atileArray<Integer, Integer>

Returns [x,y] array tuple where floats are cast to ints Useful when trying to find the tile which something is on

Returns:

  • (Array<Integer, Integer>)


229
230
231
# File 'lib/sc2ai/protocol/extensions/position.rb', line 229

def to_atile
  [x.to_i, y.to_i]
end

#to_axyArray<Float, Float>

Returns [x,y] array tuple

Returns:



222
223
224
# File 'lib/sc2ai/protocol/extensions/position.rb', line 222

def to_axy
  [x, y]
end

#to_sString

Returns:

  • (String)


235
236
237
# File 'lib/sc2ai/protocol/extensions/position.rb', line 235

def to_s
  "#<#{self.class} x=#{x} y=#{y}>"
end

#towards(other, distance) ⇒ Api::Point2D

Moves in direction towards other point by distance

Parameters:

  • other (Api::Point2D)

    The target point to move to.

  • distance (Float)

    The distance to move.

Returns:



205
206
207
208
# File 'lib/sc2ai/protocol/extensions/position.rb', line 205

def towards(other, distance)
  direction = other.subtract(self).normalize
  add(direction.multiply(distance))
end