UI: Coordinate system origin at bottom-left instead of top-left


#1

Hello,

When I draw a graphic in the paint method, I would like to use coordinates where the origin (that is the point at (0,0)) is at the bottom-left corner intead of the top-left because I find it easier to think about it.
Is there a way to change coordinates system used such that the origin would be at the bottom-left corner?

Regards,
Matt


#2

Yes, you can use AffineTransform::verticalFlip.

Usage:

void paint(juce::Graphics & g)
{
    g.addTransform(juce::AffineTransform::verticalFlip(getHeight());
}

Edit: Notice that this affects all subsequent operations on the object. For using other algorithms in-between, you may want to use Graphics::saveState/restoreState as well.

Edit2: You can also do something like this, which is less invasive:

auto tsfY = [&] (float y) { return getHeight() - y; } // (may or may not want to use getHeight() - 1)
g.drawLine(0, tsfY(0), getWidth(), tsfY(getHeight());

#3


#4

In that case, the class Graphics::ScopedSaveState does that for you and you won’t have to worry about mismatched save/restore call anymore :wink:


#5

Yes, if he doesn’t draw symmetrical things. that’s probably not what he wanted. I just read up on Apple’s flip transforms and they actually special case stuff like fonts to appear upside-down when flipped through transformation matrices.

Otherwise, you’ll have to transform each y-coordinate as in my second edit. You may even have to translate the y-coordinate by the height as well, if you want that.


#6

Thank you for the answers.

g.addTransform(juce::AffineTransform::verticalFlip(getHeight())); is what I was looking for.

I am trying to draw a graph whom points coordinates on the graph are the same than the coordinate of the g.drawEllipse function.

For instance, a points at the origin (where the ordinate and abscissa crossed) would be drawn with g.drawEllipse(0,0,diameter, diameter, lineThickness);

To do that, I added:

g.addTransform(juce::AffineTransform::verticalFlip(getHeight()));
g.addTransform(AffineTransform().translated(getWidth()/2.0,getHeight()/2.0));

Regards,
Matt