Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: [Solved] Help with rotating a texture rect around a point  (Read 3117 times)

0 Members and 1 Guest are viewing this topic.

mashedtatoes

  • Newbie
  • *
  • Posts: 23
    • View Profile
[Solved] Help with rotating a texture rect around a point
« on: October 13, 2014, 12:36:48 am »
I am trying to make a planet appear to be rotating on an axis parallel to the plane of the screen (2d game). I have a 5000 x 5000 pixel texture of randomly generated continents/oceans (here is a smaller example. imgur wont let me upload the big one. For each planet I choose a random point on this texture and set the texture rect at this position and the width/height to the diameter of the planet. Here is a drawing to help visualize what I am trying to do and here is a gif of what I have achieved so far but it isn't quite right. In the image, I want the texture rect to translate around the larger circle in a small amount each frame. As for the gif, I honestly have no clue what is causing that stretching stuff as there is nothing like that in the texture. It is possible that it is going out of the bounds of the texture because i don't check for that yet. Any help is appreciated.

Here is the code after setting the texture rect and radius of the circle,

    //this is the radius of the larger circle that the texture rect will move along
        bigRadius = (std::sqrt(2.0) + 1) * circle.getRadius() - circle.getRadius();
    //origin of the circle is set to the center of the circle. this is the point we want to translate (circle is the planets circleshape)
        point = circle.getPosition();
        //point we want to translate around
        centerPoint.x = circle.getPosition().x;
        centerPoint.y = circle.getPosition().y + bigRadius;

Here is my update function (angle is initialized to 0)
        angle += .1;
        float sin = std::sin(angle * DEGTORAD);
        float cos = std::cos(angle * DEGTORAD);
        point.x = centerPoint.x * cos - centerPoint.y * sin;
        point.y = centerPoint.x * sin + centerPoint.y * cos;
        circle.setTextureRect(sf::IntRect(point.x - circle.getRadius(), point.y - circle.getRadius(), circle.getTextureRect().width, circle.getTextureRect().height));

If you watch the gif closely, you can see that the translation is kind of working but I don't know what to do to make it work completely. I also know this is not exactly parallel to the plane of the screen but this is the best I could come up with. Anybody have any ideas?
« Last Edit: October 15, 2014, 03:32:01 am by mashedtatoes »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10998
    • View Profile
    • development blog
    • Email
AW: Help with rotating a texture rect around a point
« Reply #1 on: October 13, 2014, 01:57:49 am »
Provide a mininal and complete example. That way you'll already start narrowing down thd problem and maybe find a fix on youd own ;)

Without an example there can be toi many factors for us.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

mashedtatoes

  • Newbie
  • *
  • Posts: 23
    • View Profile
Re: Help with rotating a texture rect around a point
« Reply #2 on: October 13, 2014, 03:45:44 am »
int main(){
                //create window
                sf::RenderWindow window;
                sf::VideoMode mode;
                mode.height = 480;
                mode.width = 360;
                window.create(mode, "spinning planet");
                window.setVerticalSyncEnabled(true);
                window.setFramerateLimit(60);
               
                //create planet
                sf::CircleShape planet;
                sf::Texture map;
                map.loadFromFile("resources/PerlinNoise.png");
                planet.setRadius(40);
                planet.setOrigin(planet.getRadius(), planet.getRadius());
                planet.setPosition(window.getSize().x / 2, window.getSize().y / 2);
                planet.setTexture(&map);
                //pick the middle of the texture
                sf::Vector2i rect = sf::Vector2i(map.getSize().x / 2 - planet.getRadius(), map.getSize().y / 2 - planet.getRadius());
                planet.setTextureRect(sf::IntRect(rect.x, rect.y, 2 * planet.getRadius(), 2 * planet.getRadius()));
                float bigRadius = (std::sqrt(2.0) + 1) * planet.getRadius() - planet.getRadius();
                float angle = 0;
                sf::Vector2f point = planet.getPosition();
                sf::Vector2f centerPoint = sf::Vector2f(planet.getPosition().x, planet.getPosition().y + bigRadius);

                //main loop
                bool play = true;
                while(play){
                        sf::Event event;
                        while(window.pollEvent(event)){
                                if(event.type == sf::Event::Closed){
                                        play = false;
                                }
                        }
                        window.clear();
                        //update planet
                        angle += .1;
                        float s = std::sin(angle * DEGTORAD);
                        float c = std::cos(angle * DEGTORAD);
                        point.x = centerPoint.x * c - centerPoint.y * s;
                        point.y = centerPoint.x * s + centerPoint.y * c;
                        planet.setTextureRect(sf::IntRect(point.x - planet.getRadius(), point.y - planet.getRadius(), planet.getTextureRect().width, planet.getTextureRect().height));
                       
                        //draw/display
                        window.draw(planet);
                        window.display();
                }

                if(window.isOpen()){
                        window.close();
                }
                return 0;
        }

Here is a minimal example. You can pretty much use any large image as the texture. Just change the name in the code. I am still having the same problems after doing this though :(

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10998
    • View Profile
    • development blog
    • Email
AW: Help with rotating a texture rect around a point
« Reply #3 on: October 13, 2014, 07:23:08 am »
You might want to print out the values you set for the texture rect, they might not be what you'd expect.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

mashedtatoes

  • Newbie
  • *
  • Posts: 23
    • View Profile
Re: Help with rotating a texture rect around a point
« Reply #4 on: October 13, 2014, 09:11:31 am »
OOOOOHHHH, i'm using the point in the world coordinates and not the texture coordinates. Thanks for helping me realize that.

mashedtatoes

  • Newbie
  • *
  • Posts: 23
    • View Profile
Re: [Solved] Help with rotating a texture rect around a point
« Reply #5 on: October 15, 2014, 03:40:09 am »
I got it working now here's a gif. There is only one other problem with the texture rect not ending up in the same spot after it rotates 360 degrees but i should be able to figure that out. Now I just need to add a shader to make it look more spherical!  :D