Closed rhannequin closed 9 months ago
@JoelQ
def +(other)
self.class.as_radians(radians + other.radians)
end
This implementation doesn't allow for arithmetic operations with regular numbers:
Astronoby::Angle.as_degrees(180) + 60
# `+': undefined method `radians' for 60:Integer (NoMethodError)
I need to do the following:
angle = Astronoby::Angle.as_degrees(180)
Astronoby::Angle.as_degrees(angle.degrees + 60)
Do you think it would be worth it to allow somehow this?
angle = Astronoby::Angle.as_degrees(180)
new_angle = angle + 60
new_angle.degrees # => 240
This would be very convenient to write, but also very error prone. I don't even know how to do it because angles are stored in radians and the #+
method would have no clue what the numeric value's unit would be.
This reminds me of your suggestion to implement #cos
, but this means I have to be cautious because #cos would return a number (implicitly in radians) instead of an Angle
.
Do you have an opinion?
This implementation doesn't allow for arithmetic operations with regular numbers [...] This would be very convenient to write, but also very error prone. I don't even know how to do it because angles are stored in radians and the #+ method would have no clue what the numeric value's unit would be.
Agreed! IMO you shouldn't do arithmetic operations with raw numbers. Raw numbers are ambiguous and lead to bugs. Consider:
angle = Angle.as_degrees(180)
angle + 60
What does 60
represent? Is it an angle in degrees? An angle in radians? Some other quantity altogether such as distance in meters? A dimensionless number?
It's safer and easier to read if you do write this as:
angle = Angle.as_degrees(180)
other_angle = Angle.as_degrees(60)
new_angle = angle + other_angle
In general
Distance
by a Duration
returns a Velocity
.This reminds me of your suggestion to implement #cos, but this means I have to be cautious because #cos would return a number (implicitly in radians) instead of an Angle.
Interestingly, the value returned by trigonometric functions is not a number of radians. It is not even an angle. Instead it is a unit-less number (a ratio of two distances so the units cancel out)
The idea that you can do math between and across unit types, that this can result in new units, and that some operations are forbidden leads to the technique of dimensional analysis, where a calculation can be spot-checked for correctness by making sure that the units that come out of it are those expected
Some languages like F# can track unit math automatically for you, which is pretty cool!
This introduces several arithmetic functions in
Angle
to increase readability and developer experience.Instance methods
Angle#+
: adds two angles' values and returns an angleAngle#-
: subtracts two angles' values and returns an angleAngle#sin
: returns the numeric value (ratio) of the sine of the angleAngle#cos
: returns the numeric value (ratio) of the cosine of the angleAngle#tan
: returns the numeric value (ratio) of the tangent of the angleClass methods
Angle::asin
: returns a new angle from the radians of a inverse sine ratioAngle::acos
: returns a new angle from the radians of a inverse cosine ratioAngle::atan
: returns a new angle from the radians of a inverse tangent ratioExamples