nannou-org / nannou

A Creative Coding Framework for Rust.
https://nannou.cc/
6.03k stars 304 forks source link

Drawing rotation #305

Open freesig opened 5 years ago

freesig commented 5 years ago

I might be miss understanding this but shouldn't these both create different drawings.

    draw.rect().rotate(angle).x_y(50.0, 10).w_h(100.0, 3.0).color(DARK_RED);
    draw.rect().x_y(50.0, 10).w_h(100.0, 3.0).color(DARK_RED).rotate(angle).;

The first one would rotate the axis then move to x_y (on rotated axis) then out w_h (on rotated axis). The second would move out x_y then out w_h then rotate the axis. Like this: image

Currently they both create the same drawing. Or am I missing something here?

mitchmindtree commented 5 years ago

Ahhh so the order of the method calls don't actually affect the order of the transformations at the moment - each of those values only gets applied once building the shape is completed and always in the same order. I think there might have been a reason for this but it's been about a year now and my memory is a bit hazy! Also, I believe the current implementation of rotation doesn't rotate the whole axis or "context" - the following translation and scaling will still happen with y pointing up and x pointing right. I think maybe the Matrix type idea discussed in #194 might be better suited to "grouped" or "contextual" transformations? Maybe after v0.9 during the implementation of #253 would be a good time to review all of this behaviour together.

freesig commented 5 years ago

Yeh I agree a review would be good. I think with this implementation you are forced to rotate in the center of an object.which makes it hard to draw certain things.

mitchmindtree commented 5 years ago

Just for the record, there are a suite of methods that do let you do relative rotations, but agreed it would be nicer to have an option to use a transformation matrix style approach too.

freesig commented 5 years ago

Oh nice, it might just be that I don't understand it haha. I might make this the first thing I start on in the guide

freesig commented 5 years ago

I'm still really confused with this. I had a look through the relative rotation docs but I can't seem to figure out how to use it properly. For example lets say I want to draw a line as the normal to an arbitrary vector like this: image say the vector is:

vec2(50.0, 100.0);

Which would be drawn like:

        draw.rect()
        .x_y(25.0, 50.0)
        .w_h(5.0, 300.0)
        .rotate(-PI/4.0)
        .color(DARK_BLUE);

Then I to draw the normal I need a rect starting at pt2(2.5, 5.0) and extending out 90 degrees.

        draw.rect()
            .xy_relative(pt2(0.0, 100.0))
            .w_h(4.0, 200.0)
            .z_degrees_relative(90.0)
            .color(RED);

This results in something like: image Am I missing something fundamental here or is this just not possible with the current nannou drawing api?

mitchmindtree commented 5 years ago

The xy_relative call on the red line is still happening in "world space", not the blue line's space. The same goes for all of the other relative methods - they don't transform the whole context between drawing different shapes, they are still just describing positions or orientations in the normal world space with y pointing up and x pointing right.

So in this case, it's shifting the red line directly upwards by 100 from the centre of the blue line, rather than in a diagonal direction as if the whole transformation context is rotated along with the orientation of the blue line.

There is no way to carry through transformations between different shapes like this in nannou yet without either calculating it yourself or adding some kind of matrix or grouping API like mentioned in #194.