SFML community forums

Help => Graphics => Topic started by: Danikar on December 20, 2011, 10:41:52 am

Title: View Coordinates question
Post by: Danikar on December 20, 2011, 10:41:52 am
I wanted to use my own coordinate system in a view, so I have the following code so far

Code: [Select]
#include <SFML/Graphics.hpp>

int main (int argc, const char * argv[])
{
    const float w = 640.0f;
    const float h = 480.0f;
   
    sf::RenderWindow window(sf::VideoMode(w, h), "Coordinates Test");
    sf::View view(sf::Vector2f(0, 0), sf::Vector2f(20.0f * w / h, 20.0f));
    window.SetView(view);
   
    sf::Shape box = sf::Shape::Rectangle(0, 0, 1, 1, sf::Color::Red);
    box.SetOrigin(0.5, 0.5);
    box.SetPosition(5, 5);
   
    while (window.IsOpened()) {
        sf::Event e;
        while (window.PollEvent(e)) {
            if (e.Type == sf::Event::Closed)
                window.Close();
        }
       
        window.Clear(sf::Color::White);
       
        window.Draw(box);
       
        window.Display();
    }
   
    return EXIT_SUCCESS;
}


This gives me the coordinate system I want, except upside down. I can not find a way to flip the y-axis. Is there a way to do this that I am just missing, or can this only be done be physically changing sfml?

To set up the view's projection matrix, the sf::View class uses the following function

Code: [Select]
inline Matrix3 Matrix3::Projection(const Vector2f& center, const Vector2f& size, float rotation)
{
    // Rotation components
    float angle  = rotation * 3.141592654f / 180.f;
    float cosine = static_cast<float>(std::cos(angle));
    float sine   = static_cast<float>(std::sin(angle));
    float tx     = -center.x * cosine - center.y * sine + center.x;
    float ty     =  center.x * sine - center.y * cosine + center.y;

    // Projection components
    float a =  2.f / size.x;
    float b = -2.f / size.y;
    float c = -a * center.x;
    float d = -b * center.y;

    // Rebuild the projection matrix
    return Matrix3( a * cosine, a * sine,   a * tx + c,
                   -b * sine,   b * cosine, b * ty + d,
                    0.f,        0.f,        1.f);
}


It seems that this is where the mirroring ability is missing from. Is this standard?

Thanks for any advice.
Title: View Coordinates question
Post by: Laurent on December 20, 2011, 11:15:54 am
Have you tried to rotate the view 180°?
Title: View Coordinates question
Post by: Danikar on December 20, 2011, 07:19:48 pm
A rotation will not give me what  I need. A flip can not be made with a rotation.

This is what I want
(http://i.imgur.com/3QiEL.jpg)

This is what I have
(http://i.imgur.com/RED61.jpg)

This is what I get if I rotate 180 degrees.
(http://i.imgur.com/lwyF9.jpg)

You can also see from the rotation and flip matrices that a flip can not be made from a rotation since if cos(angle) = 1, we can't have cos(angle) = -1 also.

Code: [Select]

    float angle = 180;
    sf::Matrix3 rotation(std::cos(angle), -std::sin(angle), 0,
                         std::sin(angle),  std::cos(angle), 0,
                         0,                0,               1);
   
    sf::Matrix3 flip_y(1,  0, 0,
                       0, -1, 0,
                       0,  0, 1);
   
    sf::Matrix3 flip_x(-1, 0, 0,
                        0, 1, 0,
                        0, 0, 1);
Title: View Coordinates question
Post by: Laurent on December 20, 2011, 07:54:58 pm
Yes sorry, I thought you wanted to invert both axes.

It's not officially supported, but using a negative height should do the trick.
Title: View Coordinates question
Post by: Danikar on December 20, 2011, 07:58:18 pm
Yeah I think that is what I am going to have to do.

I tried adding support for it, but it ended up flipping the images upside down too.

Thanks.
Title: View Coordinates question
Post by: Laurent on December 20, 2011, 08:06:13 pm
Yes, if you flip the view, everything will be flipped. Flipping only the coordinates system will be much harder to achieve.