std/linear/angle
std/linear/src/angle.trb
Angle, the wrapper that keeps a quarter turn written as 90 from being read as 90 radians.
Every angle in std/linear and std/geometry is an Angle, never a bare scalar, and the unit is named at the one
place where the number comes in (Angle.degrees 90.0) and at the one place where it goes out (turn.toDegrees()).
In between the unit cannot be lost, because there is no unit - there is an Angle.
type Angle
type Angle<Scalar: Real = Float> with Add, Subtract, Negate, Multiply<Scalar>, Compare
A rotation, held in radians and constructed by the unit it is written in. Angle(1.5) is radians - the field says
so - and Angle.degrees 90.0 is the other unit, spelled out.
Angles grow from the first axis towards the second: a quarter turn takes unitX onto unitY. Whether a viewer
calls that clockwise depends on which way the program draws its second axis, and this library does not decide it.
Examples
const quarter = Angle.degrees 90.0
print "{quarter.toDegrees()} {quarter.radians}"
Pitfalls
Angle(value)andAngle.degrees(value)both take a plain number, and only the spelling says which unit it is in. A number that comes from somewhere else - a file, a protocol - becomes anAngleat the boundary and is never carried on as a bare scalar.
Open
- The three turns are written for
Floatonly, because the value of pi has to be written out. AFixedquarter turn comes fromAngle.degrees;Angle.zerois there for every scalar.
Related
Vector2.angle- the direction of a vector, as one of these.Angle.normalized- the same rotation written in(-pi, pi].
field radians
radians: Scalar
The rotation in radians.
const zero
static zero: Angle<Scalar> = Angle Scalar.zero
No rotation, over whichever scalar is asked for: Angle<Fixed>.zero.
fn degrees
static fn degrees(value: Scalar): Angle<Scalar>
The angle that many degrees is.
print Angle.degrees(180.0).radians
fn compare
fn compare(other: Angle<Scalar>): Ordering
Which of the two rotations is the smaller one, by the radians they hold.
fn add
fn add(other: Angle<Scalar>): Angle<Scalar>
The two rotations one after the other.
fn subtract
fn subtract(other: Angle<Scalar>): Angle<Scalar>
The rotation from the other one to this one.
fn negate
fn negate(): Angle<Scalar>
The same rotation the other way round.
fn multiply
fn multiply(other: Scalar): Angle<Scalar>
The rotation, that many times over.
fn toDegrees
fn toDegrees(): Scalar
The rotation in degrees.
fn sine
fn sine(): Scalar
The sine of the angle.
fn cosine
fn cosine(): Scalar
The cosine of the angle.
fn tangent
fn tangent(): Scalar
The tangent of the angle. Panics at a quarter turn, where there is none.
fn halved
fn halved(): Angle<Scalar>
Half of the rotation.
fn normalized
fn normalized(): Angle<Scalar>
The same rotation written in (-pi, pi]: what two headings have to be reduced to before they are compared.
It goes around the circle rather than dividing by a whole turn, because a body that is generic over the scalar cannot write one: the sine and the cosine of a rotation do not care how many turns it carries, and the arc tangent of that pair is the rotation without them.
extend Angle<Scalar>
extend<Scalar: Real> Angle<Scalar>
const quarterTurn
static quarterTurn: Angle<Scalar> = Angle Scalar.pi.halved()
A quarter turn: the first axis onto the second.
const halfTurn
static halfTurn: Angle<Scalar> = Angle Scalar.pi
Half a turn.
const fullTurn
static fullTurn: Angle<Scalar> = Angle Scalar.tau
A whole turn.