linebender / kurbo

A Rust library for manipulating curves
Apache License 2.0
697 stars 67 forks source link

Missing impl: Mul for Affine * Vec2 #360

Closed waywardmonkeys closed 1 month ago

waywardmonkeys commented 1 month ago

@crockeo pointed out that there's no impl Mul for Affine and Vec2.

raphlinus commented 1 month ago

Yeah, this is on purpose. The mathematical meaning is ambiguous. Is it the same as Point, or does only the matrix apply and not the translation?

waywardmonkeys commented 1 month ago

The code they had (using their own multiply):

pub fn arrow(from: Point, to: Point) -> [Line; 3] {
    let backwards_direction = (from.to_vec2() - to.to_vec2()).normalize();

    let clockwise_arm =
        to + (Mat2::rotate(ARROW_ARM_ANGLE) * backwards_direction * ARROW_ARM_LENGTH);
    let anticlockwise_arm =
        to + (Mat2::rotate(-ARROW_ARM_ANGLE) * backwards_direction * ARROW_ARM_LENGTH);

    [
        Line::new(from, to),
        Line::new(to, clockwise_arm),
        Line::new(to, anticlockwise_arm),
    ]
}
raphlinus commented 1 month ago

I think the principled way to do this is to_point() on backwards_direction.

crockeo commented 1 month ago

Your explanation of why one wouldn't implement Mul between Affine and Vec2 makes sense, thanks! This was more or less my gut feeling, but I took linear algebra years ago so I wasn't confident anymore 😅.

To me the "nicest" implementation would be to use Affine directly to express the transform:

I didn't figure out the math at the time, but I was planning on giving it another go whenever I get around to that TODO.

raphlinus commented 1 month ago

I think I'll close this, as there isn't consensus it should be part of the API, and it seems like there's another way to get the same effect. Thanks for the input!