2020-07-04 19:25:53 -04:00
|
|
|
package d2vector
|
|
|
|
|
2020-07-09 08:30:55 -04:00
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"math"
|
|
|
|
)
|
2020-07-04 19:25:53 -04:00
|
|
|
|
2020-07-09 08:30:55 -04:00
|
|
|
const subTilesPerTile float64 = 5
|
|
|
|
|
|
|
|
// Position is a vector in world space. The stored value is the one returned by Position.World()
|
2020-07-04 19:25:53 -04:00
|
|
|
type Position struct {
|
2020-07-09 08:30:55 -04:00
|
|
|
Vector
|
2020-07-04 19:25:53 -04:00
|
|
|
}
|
|
|
|
|
2020-07-09 08:30:55 -04:00
|
|
|
// NewPosition creates a new Position at the given float64 world position.
|
2020-07-04 19:25:53 -04:00
|
|
|
func NewPosition(x, y float64) *Position {
|
2020-07-09 08:30:55 -04:00
|
|
|
p := &Position{NewVector(x, y)}
|
|
|
|
p.checkValues()
|
|
|
|
|
|
|
|
return p
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set sets this position to the given x and y values.
|
|
|
|
func (p *Position) Set(x, y float64) {
|
|
|
|
p.x, p.y = x, y
|
|
|
|
p.checkValues()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *Position) checkValues() {
|
|
|
|
if math.IsNaN(p.x) || math.IsNaN(p.y) {
|
|
|
|
panic(fmt.Sprintf("float value is NaN: %s", p.Vector))
|
|
|
|
}
|
|
|
|
|
|
|
|
if math.IsInf(p.x, 0) || math.IsInf(p.y, 0) {
|
|
|
|
panic(fmt.Sprintf("float value is Inf: %s", p.Vector))
|
|
|
|
}
|
2020-07-04 19:25:53 -04:00
|
|
|
}
|
|
|
|
|
2020-07-09 08:30:55 -04:00
|
|
|
// World is the position, where 1 = one map tile.
|
|
|
|
func (p *Position) World() *Vector {
|
|
|
|
return &p.Vector
|
2020-07-04 19:25:53 -04:00
|
|
|
}
|
|
|
|
|
2020-07-09 08:30:55 -04:00
|
|
|
// Tile is the tile position, always a whole number.
|
|
|
|
func (p *Position) Tile() *Vector {
|
2020-07-04 19:25:53 -04:00
|
|
|
c := p.World().Clone()
|
|
|
|
return c.Floor()
|
|
|
|
}
|
|
|
|
|
2020-07-09 08:30:55 -04:00
|
|
|
// TileOffset is the offset from the tile position, always < 1.
|
|
|
|
func (p *Position) TileOffset() *Vector {
|
2020-07-04 19:25:53 -04:00
|
|
|
c := p.World().Clone()
|
|
|
|
return c.Subtract(p.Tile())
|
|
|
|
}
|
|
|
|
|
2020-07-09 08:30:55 -04:00
|
|
|
// SubWorld is the position, where 5 = one map tile.
|
|
|
|
func (p *Position) SubWorld() *Vector {
|
2020-07-04 19:25:53 -04:00
|
|
|
c := p.World().Clone()
|
2020-07-09 08:30:55 -04:00
|
|
|
return c.Scale(subTilesPerTile)
|
2020-07-04 19:25:53 -04:00
|
|
|
}
|
|
|
|
|
2020-07-09 08:30:55 -04:00
|
|
|
// SubTile is the tile position in sub tiles, always a multiple of 5.
|
|
|
|
func (p *Position) SubTile() *Vector {
|
2020-07-04 19:25:53 -04:00
|
|
|
c := p.Tile().Clone()
|
2020-07-09 08:30:55 -04:00
|
|
|
return c.Scale(subTilesPerTile)
|
2020-07-04 19:25:53 -04:00
|
|
|
}
|
|
|
|
|
2020-07-09 08:30:55 -04:00
|
|
|
// SubTileOffset is the offset from the sub tile position in sub tiles, always < 1.
|
|
|
|
func (p *Position) SubTileOffset() *Vector {
|
2020-07-04 19:25:53 -04:00
|
|
|
c := p.SubWorld().Clone()
|
|
|
|
return c.Subtract(p.SubTile())
|
|
|
|
}
|