Skip to content
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

Math cleanup #523

Merged
merged 6 commits into from
May 5, 2022
Merged

Math cleanup #523

merged 6 commits into from
May 5, 2022

Conversation

connor-lennox
Copy link
Contributor

Addresses #518 .

The work here is split into two main sections:

  1. Additions to fj-math that forward behaviour from nalgebra and parry
  2. Reworking components in fj-viewer and fj-kernel to use only the types from fj-math

One major change is the conversion of fj-math::Transform from wrapping a TGeneral to TAffine nalgebra::Transform. This doesn't have any impact on anything yet (since the TGeneral capabilities were not being used anywhere) but it's something to consider for if fj-math::Transform becomes more generalized in the future.

As always, happy to discuss these changes either here or on Matrix. This is (one of) my first forays into open-source Rust so please don't be afraid to pick it apart and show me how things could be better implemented.

@hannobraun
Copy link
Owner

Thank you for the pull request, @connor-lennox! I've had a quick look, and this looks good. I'll do a proper review later today.

This is (one of) my first forays into open-source Rust so please don't be afraid to pick it apart and show me how things could be better implemented.

Understood. I'll be extra nitpicky then 😁

hannobraun
hannobraun previously approved these changes May 5, 2022
Copy link
Owner

@hannobraun hannobraun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, @connor-lennox, this looks great!

I've found one case, where your modifications changed the behavior of the application (mouse wheel input). I've left a comment with a suggestion there. I think I can accept my own suggestion after submitting the review, and merge this immediately.

I've left a bunch of other comment with feedback and suggestions. All of them are optional, and some points (the ones where I noted that I'm being nitpicky), I wouldn't even have mentioned, if you hadn't specifically encouraged the feedback.

One additional note (also nitpicky): Some of the commits could be split into multiple smaller ones, with each smaller commit being focused on one specific change. If some changes were uncontroversial, while others required more discussion, I might want to merge the uncontroversial ones immediately. That would be easier, if every change were its own commit. Doesn't make a difference in this case though.

Feel free to follow up with another pull request that incorporates (some of) my feedback, or not, as you see fit.

@@ -1,5 +1,27 @@
use super::{Point, Scalar};

use parry2d_f64::utils::point_in_triangle::{corner_direction, Orientation};
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, this is going to be extra-nitpicky. The style that most of Fornjot's code follows is to keep a specific order of imports: First from the standard library, then from 3rd-party libraries, then from crate::, the relative imports (self::, super::). This new import breaks that order.

This is not important, and I wouldn't have said anything, if you hadn't requested the extra attention, but it can make code slightly more readable, by making imports slightly easier to find. It's also what rust-analyzer does by default, if you use it to automatically add an import (at least in VS Code).

Comment on lines +5 to +23
/// Winding direction of a triangle.
pub enum Winding {
/// Counter-clockwise
Ccw,
/// Clockwise
Cw,
/// Neither (straight lines)
None,
}

impl From<Orientation> for Winding {
fn from(o: Orientation) -> Self {
match o {
Orientation::Ccw => Winding::Ccw,
Orientation::Cw => Winding::Cw,
Orientation::None => Winding::None,
}
}
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer ordering code from high-level to low-level. In this case, this would mean first Triangle, then stuff triangle uses or returns further down.

I think this makes code easier to read sequentially, as it's easier to understand the high-level concepts first. By the time you get to the details, you've already seen what the module is about and how the details are used, which makes it easier to understand those too.

By doing this consistently, it makes things within a module also easier to find.

Again, this is nitpicky and not that important.

Also, I don't think we need Winding::None, as Triangle is validated on construction. We can just panic when encountering Orientation::None (maybe using unreachable!()), as that would be a bug in our code somewhere.

Comment on lines +82 to +83
let [v0, v1, v2] = self.points;
corner_direction(&v0.to_na(), &v1.to_na(), &v2.to_na()).into()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternative (not tested, might not compile):

Suggested change
let [v0, v1, v2] = self.points;
corner_direction(&v0.to_na(), &v1.to_na(), &v2.to_na()).into()
let [v0, v1, v2] = self.points.map(|point| point.to_na());
corner_direction(&v0, &v1, &v2).into()

@@ -58,6 +58,11 @@ impl<const D: usize> Point<D> {
coords: self.coords.to_xyz(),
}
}

/// Gives the distance between two Points.
pub fn distance(p1: &Point<D>, p2: &Point<D>) -> Scalar {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternative:

Suggested change
pub fn distance(p1: &Point<D>, p2: &Point<D>) -> Scalar {
pub fn distance_to(&self, other: &Point<D>) -> Scalar {

Not sure if that's actually better. It might be a bit nicer to call.

@@ -1,12 +1,20 @@
use std::ops;

use nalgebra::Perspective3;

use super::{Aabb, Point, Segment, Triangle, Vector};

/// A transform
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// A transform
/// An affine transform

Comment on lines +37 to +41
position: [
point.x.into_f32(),
point.y.into_f32(),
point.z.into_f32(),
],
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be shortened:

Suggested change
position: [
point.x.into_f32(),
point.y.into_f32(),
point.z.into_f32(),
],
position: point.coords.components.map(|scalar| scalar.into_f32()),

crates/fj-viewer/src/input/handler.rs Outdated Show resolved Hide resolved
Comment on lines +54 to +56
* Transform::translation(Vector::from_components_f64(
[offset.x.into(), offset.y.into(), 0.0],
));
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be shortened, I think:

Suggested change
* Transform::translation(Vector::from_components_f64(
[offset.x.into(), offset.y.into(), 0.0],
));
* Transform::translation(Vector::from(
[offset.x, offset.y, 0.0],
));

Or even shorter, although maybe less clear:

Suggested change
* Transform::translation(Vector::from_components_f64(
[offset.x.into(), offset.y.into(), 0.0],
));
* Transform::translation(offset.to_xyz());

Comment on lines +29 to +30
let rotate_around: Vector<3> =
self.focus_point.0.unwrap_or_else(Point::origin).coords;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the explicit type annotation?

Suggested change
let rotate_around: Vector<3> =
self.focus_point.0.unwrap_or_else(Point::origin).coords;
let rotate_around =
self.focus_point.0.unwrap_or_else(Point::origin).coords;


let f = 0.005;

let angle_x = diff_y * f;
let angle_y = diff_x * f;

let trans = Translation::from(rotate_around);
let trans = Transform::translation(rotate_around);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, this is nitpicky, but we're rotation around a point, not a vector. So maybe leave rotate_around as a Point, and add the .coords here, where a vector is needed:

Suggested change
let trans = Transform::translation(rotate_around);
let trans = Transform::translation(rotate_around.coords);

@hannobraun hannobraun merged commit ca75e22 into hannobraun:main May 5, 2022
@connor-lennox connor-lennox deleted the math-cleanup branch May 6, 2022 16:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants