-
Notifications
You must be signed in to change notification settings - Fork 2
Cylinder wrap math #13
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
base: master
Are you sure you want to change the base?
Conversation
Adds unconstrained quadrant, which is always valid. Writes conditions to assert ifNotValid instead.
The long and short side of right angled triangle was flipped.
double ATan2OnPositiveRange(const SimTK::Vec2 point) | ||
{ | ||
const double angle = std::atan2(point[1], point[0]); | ||
return angle < 0.? angle + c_TAU : angle; |
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.
Reformat: expr ? true : false
(space before ?
)
return angle < 0.? angle + c_TAU : angle; | ||
} | ||
|
||
class Angle final { |
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.
Design vs. usage vary.
- If the intention is that
getValue
always returns a value in the range[0..2pi]
then thedouble
ctor should enforce the fmod-like behavior, or have aUnsafe_AngleAlreadyKnownToBeInRange
tag argument to indicate to downstream code that the caller "knows what they're doing" - If the only reason to have the
double
argument is to facilitateoperator+
then you should make thedouble
constructor private andfriend Angle operator+(Angle, Angle);
, so that the operator is allowed to skip the invariant check (this is what has been done, but I'm guessing the ctor is public for another reason) - If any downstream code should be able to provide any value then the ctor should
fmod
the argument NaN
forms a 2nd form of the state (i.e. "bad state"). Ensure that's relevant (e.g. rather than "identity" -0.0
)
|
||
class Angle final { | ||
// Construct from angle already on range [0...2pi]. | ||
Angle(double angleChecked): _value(angleChecked) |
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.
explicit
public: | ||
Angle() = default; | ||
|
||
Angle(const SimTK::Vec2& point) : |
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.
explicit
(note: this ctor does enforce the [0..2pi]
class invariant)
Angle(double angleChecked): _value(angleChecked) | ||
{} | ||
|
||
public: |
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.
public:
indentation usually matches class
, not the same level as the things under public
scope
// wrapping path on a circle. | ||
namespace { | ||
|
||
// Struct for holding a generic pair, that differ in the wrapping direction. |
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.
You had better have a very good reason to be using templating, std::function
, rvalue semantics (&&
), and varadaic templates in one class here.
|
||
// Computes for both positive and negative wrapping directions, the tangent | ||
// line path segments. | ||
PositiveAndNegativeRotatingPair<PathSegment<TangentLine>> |
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.
The templating is getting a bit OTT here
const PathSegment<BothTangentLines> tangentLines(path, circleRadius); | ||
|
||
// Get one of the possible paths by setting the rotation direction. | ||
auto GetPathSegmentsGivenDirection = [&tangentLines]( |
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.
The payoff for std::function
, forwarding, etc. did not justify this bit - just compute it and pass it into a simpler struct/class imo.
CircleWrap TakeBestPath( | ||
PositiveAndNegativeRotatingPair<CircleWrap> possibleWrappings) | ||
{ | ||
return TakeBestPath(possibleWrappings.positive, |
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.
Formatting
possibleWrappings.negative); | ||
} | ||
|
||
// Computes the best wrapping path on a circle. |
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.
Stoppped reading around here - no time
Refactors the cylinder wrapping math.
Still need to iron out some details, so it is more about the overall structure.