-
Notifications
You must be signed in to change notification settings - Fork 628
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[wpiunits] Add absolute value and copy sign functionality #7358
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These operations do not make sense on an element of the SO(2) group. Rotation2d is a 2D unit vector, not an Euler angle. If you want an Euler angle, use a double
or Angle
.
The internal value field should be treated as if it doesn't exist, since it's a hack to prevent implicit wrapping in the constructor. Any operations on the Rotation2d don't preserve it. I’ve wanted to get rid of the value field, but I was told we couldn’t because it would break too much user code, but it will be removed for 2027. We originally took it from 254's geometry library, but they didn't intend the value field to be used in this way either; we just didn't realize that at the time: https://www.chiefdelphi.com/t/possible-bugs-in-rotation2d-and-rotation3d-java/474140/11
Should the methods be removed then, or should I instead be operating using |
The functions should be removed from Rotation2d. I have no opinion on them being in the measure class though. Rust takes that extension method approach as opposed to providing free functions. |
* @param other measure from which to take sign | ||
* @return a new measure with the sign from another measure | ||
*/ | ||
default Measure<U> copySign(Measure<U> other) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would ideally be called signum() and have the same semantics as the Java standard library.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is slightly different than signum()
. Math.signum()
simply returns +1, 0 or -1 based on the sign of the input. This method copies the sign of the input variable, but maintains the magnitude.
Its similar to Math.copySign()
.
https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#copySign-double-double-
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function returns the wrong result if this
is nonzero and other
is zero. It inverts the sign when it shouldn't since the signum() return values don't match.
You should probably just use Math.copySign()
on the base unit magnitude.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I get an error when I try to use Math.copySign()
.
Type mismatch: cannot convert from Measure<capture#1-of ?> to Measure<U>
/**
* Take the sign of another measure.
* @param other measure from which to take sign
* @return a new measure with the sign from another measure
*/
default Measure<U> copySign(Measure<U> other) {
return baseUnit().of(Math.copySign(this.baseUnitMagnitude(), other.baseUnitMagnitude()));
}
But if I do
if (other.isEquivalent(baseUnit().zero()) && baseUnitMagnitude() < 0.0) return times(-1);
else return times(other).baseUnitMagnitude() >= 0.0 ? this : times(-1);
its fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unit.of
returns a wildcarded Measure<?>
because the self-type isn't known. You'd need to cast to Measure<U>
.
Another issue is nonlinear units. What's the absolute value of -10°C? Using the base unit (Kelvin), it's still -10°C (263.15K); but using the relative unit Celsius it'd be 10°C, which would be treated as 283.15K in any math operations
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps abs()
should also take in the desired Unit?
Also, how would I resolve an unchecked cast for the wildcard Measure<?>
?
Is there anything else needed for this to be merged? |
Absolute value and copy sign are some common methods that I use, its kinda annoying to need to unwrap the object to do these common operations.