2021-09-02 20:17:45 +10:00
|
|
|
package engine
|
|
|
|
|
|
|
|
import (
|
2021-09-07 13:28:44 +10:00
|
|
|
"fmt"
|
2021-09-02 20:17:45 +10:00
|
|
|
"image"
|
|
|
|
"strconv"
|
|
|
|
)
|
|
|
|
|
2021-09-07 13:28:44 +10:00
|
|
|
// Int3 is a an element of int^3.
|
|
|
|
type Int3 struct {
|
2021-09-02 20:17:45 +10:00
|
|
|
X, Y, Z int
|
|
|
|
}
|
|
|
|
|
2021-09-07 13:28:44 +10:00
|
|
|
// Pt3(x, y, z) is shorthand for Int3{x, y, z}.
|
|
|
|
func Pt3(x, y, z int) Int3 {
|
|
|
|
return Int3{x, y, z}
|
2021-09-02 20:17:45 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
// String returns a string representation of p like "(3,4,5)".
|
2021-09-07 13:28:44 +10:00
|
|
|
func (p Int3) String() string {
|
2021-09-02 20:17:45 +10:00
|
|
|
return "(" + strconv.Itoa(p.X) + "," + strconv.Itoa(p.Y) + "," + strconv.Itoa(p.Z) + ")"
|
|
|
|
}
|
|
|
|
|
|
|
|
// XY applies the Z-forgetting projection. (It returns just X and Y.)
|
2021-09-07 13:28:44 +10:00
|
|
|
func (p Int3) XY() image.Point {
|
2021-09-08 17:08:21 +10:00
|
|
|
return image.Point{X: p.X, Y: p.Y}
|
|
|
|
}
|
|
|
|
|
|
|
|
// XZ applies the Y-forgetting projection. (It returns just X and Z (as Y).)
|
|
|
|
func (p Int3) XZ() image.Point {
|
|
|
|
return image.Point{X: p.X, Y: p.Z}
|
2021-09-02 20:17:45 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
// Add performs vector addition.
|
2021-09-07 13:28:44 +10:00
|
|
|
func (p Int3) Add(q Int3) Int3 {
|
|
|
|
return Int3{p.X + q.X, p.Y + q.Y, p.Z + q.Z}
|
2021-09-02 20:17:45 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
// Sub performs vector subtraction.
|
2021-09-07 13:28:44 +10:00
|
|
|
func (p Int3) Sub(q Int3) Int3 {
|
2021-09-02 20:17:45 +10:00
|
|
|
return p.Add(q.Neg())
|
|
|
|
}
|
|
|
|
|
|
|
|
// CMul performs componentwise multiplication.
|
2021-09-07 13:28:44 +10:00
|
|
|
func (p Int3) CMul(q Int3) Int3 {
|
|
|
|
return Int3{p.X * q.X, p.Y * q.Y, p.Z * q.Z}
|
2021-09-02 20:17:45 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
// Mul performs scalar multiplication.
|
2021-09-07 13:28:44 +10:00
|
|
|
func (p Int3) Mul(k int) Int3 {
|
|
|
|
return Int3{p.X * k, p.Y * k, p.Z * k}
|
2021-09-02 20:17:45 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
// CDiv performs componentwise division.
|
2021-09-07 13:28:44 +10:00
|
|
|
func (p Int3) CDiv(q Int3) Int3 {
|
|
|
|
return Int3{p.X / q.X, p.Y / q.Y, p.Z / q.Z}
|
2021-09-02 20:17:45 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
// Div performs scalar division by k.
|
2021-09-07 13:28:44 +10:00
|
|
|
func (p Int3) Div(k int) Int3 {
|
|
|
|
return Int3{p.X / k, p.Y / k, p.Z / k}
|
2021-09-02 20:17:45 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
// Neg returns the vector pointing in the opposite direction.
|
2021-09-07 13:28:44 +10:00
|
|
|
func (p Int3) Neg() Int3 {
|
|
|
|
return Int3{-p.X, -p.Y, -p.Z}
|
2021-09-02 20:17:45 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
// Coord returns the components of the vector.
|
2021-09-07 13:28:44 +10:00
|
|
|
func (p Int3) Coord() (x, y, z int) {
|
2021-09-02 20:17:45 +10:00
|
|
|
return p.X, p.Y, p.Z
|
|
|
|
}
|
|
|
|
|
2021-09-04 12:51:51 +10:00
|
|
|
// Sign returns a sign vector.
|
2021-09-07 13:28:44 +10:00
|
|
|
func (p Int3) Sign() Int3 {
|
|
|
|
return Int3{sign(p.X), sign(p.Y), sign(p.Z)}
|
2021-09-04 12:51:51 +10:00
|
|
|
}
|
|
|
|
|
2021-09-06 17:50:17 +10:00
|
|
|
// Dot returns the dot product of the two vectors.
|
2021-09-07 13:28:44 +10:00
|
|
|
func (p Int3) Dot(q Int3) int {
|
2021-09-06 17:50:17 +10:00
|
|
|
return p.X*q.X + p.Y*q.Y + p.Z*q.Z
|
|
|
|
}
|
|
|
|
|
2021-09-04 12:51:51 +10:00
|
|
|
func sign(m int) int {
|
|
|
|
if m == 0 {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
if m < 0 {
|
|
|
|
return -1
|
|
|
|
}
|
|
|
|
return 1
|
|
|
|
}
|
2021-09-07 13:28:44 +10:00
|
|
|
|
|
|
|
func signf(m float64) float64 {
|
|
|
|
if m == 0 {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
if m < 0 {
|
|
|
|
return -1
|
|
|
|
}
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
// Float3 is an element of float64^3.
|
|
|
|
type Float3 struct {
|
|
|
|
X, Y, Z float64
|
|
|
|
}
|
|
|
|
|
|
|
|
// String returns a string representation of p like "(3.0,4.0,5.0)".
|
|
|
|
func (p Float3) String() string {
|
|
|
|
return fmt.Sprintf("(%f,%f,%f)", p.X, p.Y, p.Z)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add performs vector addition.
|
|
|
|
func (p Float3) Add(q Float3) Float3 {
|
|
|
|
return Float3{p.X + q.X, p.Y + q.Y, p.Z + q.Z}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Sub performs vector subtraction.
|
|
|
|
func (p Float3) Sub(q Float3) Float3 {
|
|
|
|
return p.Add(q.Neg())
|
|
|
|
}
|
|
|
|
|
|
|
|
// CMul performs componentwise multiplication.
|
|
|
|
func (p Float3) CMul(q Float3) Float3 {
|
|
|
|
return Float3{p.X * q.X, p.Y * q.Y, p.Z * q.Z}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Mul performs scalar multiplication.
|
|
|
|
func (p Float3) Mul(k float64) Float3 {
|
|
|
|
return Float3{p.X * k, p.Y * k, p.Z * k}
|
|
|
|
}
|
|
|
|
|
|
|
|
// CDiv performs componentwise division.
|
|
|
|
func (p Float3) CDiv(q Float3) Float3 {
|
|
|
|
return Float3{p.X / q.X, p.Y / q.Y, p.Z / q.Z}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Div performs scalar division by k.
|
|
|
|
func (p Float3) Div(k float64) Float3 {
|
|
|
|
return Float3{p.X / k, p.Y / k, p.Z / k}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Neg returns the vector pointing in the opposite direction.
|
|
|
|
func (p Float3) Neg() Float3 {
|
|
|
|
return Float3{-p.X, -p.Y, -p.Z}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Coord returns the components of the vector.
|
|
|
|
func (p Float3) Coord() (x, y, z float64) {
|
|
|
|
return p.X, p.Y, p.Z
|
|
|
|
}
|
|
|
|
|
|
|
|
// Sign returns a sign vector.
|
|
|
|
func (p Float3) Sign() Float3 {
|
|
|
|
return Float3{signf(p.X), signf(p.Y), signf(p.Z)}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Dot returns the dot product of the two vectors.
|
|
|
|
func (p Float3) Dot(q Float3) float64 {
|
|
|
|
return p.X*q.X + p.Y*q.Y + p.Z*q.Z
|
|
|
|
}
|