2021-09-08 20:08:57 +10:00
|
|
|
package geom
|
2021-09-05 17:22:46 +10:00
|
|
|
|
2021-09-07 13:14:42 +10:00
|
|
|
import "image"
|
2021-09-05 17:22:46 +10:00
|
|
|
|
2021-09-07 14:00:50 +10:00
|
|
|
// IntProjection holds an integer projection definition.
|
|
|
|
// It is designed for projecting Z onto X and Y with integer fractions as would
|
|
|
|
// be used in e.g. a diametric projection (IntProjection{X:0, Y:-2}).
|
2021-09-07 13:14:42 +10:00
|
|
|
type IntProjection image.Point
|
2021-09-05 17:22:46 +10:00
|
|
|
|
2021-09-07 13:14:42 +10:00
|
|
|
// Project performs an integer parallel projection of a 3D coordinate into 2D.
|
|
|
|
// If π.X = 0, the x returned is p.X; similarly for π.Y and y.
|
|
|
|
// Otherwise, x projects to x + z/π.X and y projects to y + z/π.Y.
|
2021-09-07 13:28:44 +10:00
|
|
|
func (π IntProjection) Project(p Int3) image.Point {
|
2021-09-07 13:14:42 +10:00
|
|
|
/*
|
|
|
|
I'm using the π character because I'm a maths wanker.
|
|
|
|
|
|
|
|
Dividing is used because there's little reason for an isometric
|
|
|
|
projection in a game to exaggerate the Z position.
|
2021-09-05 17:22:46 +10:00
|
|
|
|
2021-09-09 19:11:25 +10:00
|
|
|
Integers are used to preserve "pixel perfect" calculation in case you
|
|
|
|
are making the next Celeste.
|
2021-09-07 13:14:42 +10:00
|
|
|
*/
|
|
|
|
q := p.XY()
|
|
|
|
if π.X != 0 {
|
|
|
|
q.X += p.Z / π.X
|
|
|
|
}
|
|
|
|
if π.Y != 0 {
|
|
|
|
q.Y += p.Z / π.Y
|
|
|
|
}
|
|
|
|
return q
|
2021-09-05 17:22:46 +10:00
|
|
|
}
|