Newer
Older
package pixel
import (
"fmt"
"math"
"math/cmplx"
)
// Vec is a 2d vector type. It is unusually implemented as complex128 for convenience. Since
// Go does not allow operator overloading, implementing vector as a struct leads to a bunch of
// methods for addition, subtraction and multiplication of vectors. With complex128, much of
// this functionality is given through operators.
//
// Create vectors with the V constructor:
//
// u := pixel.V(1, 2)
// v := pixel.V(8, -3)
//
// Add and subtract them using the standard + and - operators:
//
// w := u + v
// fmt.Println(w) // Vec(9, -1)
// fmt.Println(u - v) // Vec(-7, 5)
//
// Additional standard vector operations can be obtained with methods:
//
// String returns the string representation of a vector u.
//
// u := pixel.V(4.5, -1.3)
// u.String() // returns "Vec(4.5, -1.3)"
// fmt.Println(u) // Vec(4.5, -1.3)
func (u Vec) String() string {
return fmt.Sprintf("Vec(%v, %v)", u.X(), u.Y())
return real(u)
}
// Y returns the y coordinate of a vector u.
// XY returns the components of a vector in two return values.
func (u Vec) XY() (x, y float64) {
return real(u), imag(u)
}
return cmplx.Abs(complex128(u))
}
// Angle returns the angle between a vector u and the x-axis. The result is in the range [-Pi, Pi].
return cmplx.Phase(complex128(u))
}
// Unit returns a vector of length 1 with the same angle as u.
// Scaled returns a vector u multiplied by c.
func (u Vec) Scaled(c float64) Vec {
return u * V(c, 0)
}
// Rotated returns a vector u rotated by the given angle in radians.
sin, cos := math.Sincos(angle)
return u * V(cos, sin)
return u.X()*v.X() + u.Y()*v.Y()
}
// Cross return the cross product of vectors u and v.
// Rect is a 2d rectangle aligned with the axis of the coordinate system. It has a position
// and a size.
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
//
// You can manipulate the position and the size using the usual vector operations.
type Rect struct {
Pos, Size Vec
}
// R returns a new 2d rectangle with the given position (x, y) and size (w, h).
func R(x, y, w, h float64) Rect {
return Rect{
Pos: V(x, y),
Size: V(w, h),
}
}
// String returns the string representation of a rectangle.
//
// r := pixel.R(100, 50, 200, 300)
// r.String() // returns "Rect(100, 50, 200, 300)"
// fmt.Println(r) // Rect(100, 50, 200, 300)
func (r Rect) String() string {
return fmt.Sprintf("Rect(%v, %v, %v, %v)", r.X(), r.Y(), r.W(), r.H())
}
// X returns the x coordinate of the position of a rectangle.
func (r Rect) X() float64 {
return r.Pos.X()
}
// Y returns the y coordinate of the position of a rectangle
func (r Rect) Y() float64 {
return r.Pos.Y()
}
// W returns the width of a rectangle.
func (r Rect) W() float64 {
return r.Size.X()
}
// H returns the height of a rectangle.
func (r Rect) H() float64 {
return r.Size.Y()
}
// XYWH returns all of the four components of a rectangle in four return values.
func (r Rect) XYWH() (x, y, w, h float64) {
return r.X(), r.Y(), r.W(), r.H()
}
// Center returns the position of the center of a rectangle.
func (r Rect) Center() Vec {
return r.Pos + r.Size.Scaled(0.5)
}