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

Author Topic: Get an image from a shape  (Read 1296 times)

0 Members and 1 Guest are viewing this topic.

Ravenons

  • Newbie
  • *
  • Posts: 3
    • View Profile
Get an image from a shape
« on: December 26, 2012, 11:13:04 pm »
Hi, I was curious about the minimum number of points in a CircleShape you need given the radius so the circle is as perfect as possible. I mean, the number of points that makes the circle equal, pixel to pixel, to another circle created with the same number of points plus one. So if you increase the number of points, the circle is not going to improve.

So I wrote a little test that test this. But then I realized that getTexture() from sf::Shape doesn't behave as I expected (it's not designed for what I thought). I tried to get the texture from the shape, then the image from the texture, and finally, the pointer to the array of pixels, so I can test if the two images are equal if the arrays are equal.

Now that you know the problem, please, tell me how to get an image from a shape or an easier way to make the test I'm making.

Thanks in advance.

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Get an image from a shape
« Reply #1 on: December 26, 2012, 11:38:16 pm »
Draw to a RenderWindow, get window contents into texture, get image from texture, get pixel data from image. Repeat and compare with next one. Simplest and probably not most efficient.
Back to C++ gamedev with SFML in May 2023

Ravenons

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Get an image from a shape
« Reply #2 on: December 27, 2012, 12:45:26 am »
Thanks, it does the trick for this test! :)

I did it using the method capture() from RenderWindow, that returns an Image, I'm not sure if you mean this. Maybe I'll check the source code for CircleShape, so I can see how it's generated. If someone has anything interesting to say about this or something related, I'll be glad to hear it :D

As soon as I get the results from the test (maybe tomorrow, I need to sleep), I'll post them here just in case someone find it interesting. Maybe pointCount and pointCount+1 generates the same shape, but pointCount+2 and in general, pointCount+n doesn't, so I'll check this case too.
« Last Edit: December 27, 2012, 12:48:40 am by Ravenons »

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Get an image from a shape
« Reply #3 on: December 27, 2012, 01:08:44 am »
I forgot capture, I meant to copy window content into texture and then get image from texture but capture is better for that.
I think shapes are just triangle fans with some point inside as first, and all points on outline as next ones with first being duplicated so it closes. That's why it has to be convex.
Back to C++ gamedev with SFML in May 2023

Ravenons

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Get an image from a shape
« Reply #4 on: December 27, 2012, 04:18:01 am »
Yes, I guess so, but I'm wondering how are this fans generated. Anyway, the results of the test:

The condition is that given the radius and the pointCount, for every i greater than zero, CircleShape(radius, pointCount) equals bit-to-bit to CircleShape(radius, pointCount + i)

Ok, I didn't test it for every i greater than zero, but at least 20 values from the last change :P

radius -> pointCount

1 -> 5
2 -> 5
3 -> 14
4 -> 10
5 -> 22
6 -> 10
7 -> 32
8 -> 20
9 -> 18
10 -> 26
11 -> 51
12 -> 21
13 -> 64
14 -> 37
15 -> 71

It's kind of surprising for me, especially the change from 7 to 9 (it decreases).

Here's the code, if you want to repeat the test. Just use the arrows to increase or decrease both values:


#include <iostream>
#include <SFML/Graphics.hpp>

#define SCREEN_WIDTH 200
#define SCREEN_HEIGHT 200
#define BIT_DEPTH 32

int main() {

        sf::RenderWindow renderWindow(
                        sf::VideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, BIT_DEPTH),
                        "CircleShape test");

        float radius = 10;
        int pointCount = 4;
        sf::CircleShape circle;

        while (renderWindow.isOpen()) {

                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) {
                        pointCount--;
                        std::cout << "radius=" << radius << "; pointCount=" << pointCount << std::endl;
                } else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) {
                        pointCount++;
                        std::cout << "radius=" << radius << "; pointCount=" << pointCount << std::endl;
                } else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) {
                        radius = (float) (((int) radius)-1);
                        std::cout << "radius=" << radius << "; pointCount=" << pointCount << std::endl;
                } else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) {
                        radius = (float) (((int) radius)+1);
                        std::cout << "radius=" << radius << "; pointCount=" << pointCount << std::endl;
                }

                circle.setRadius(radius);
                circle.setPointCount(pointCount);

                sf::Event event;
                while (renderWindow.pollEvent(event)) {
                        if (event.type == sf::Event::Closed
                                        || (event.type == sf::Event::KeyPressed
                                                        && event.key.code == sf::Keyboard::Escape)) {
                                renderWindow.close();
                        }
                }

                renderWindow.clear();
                renderWindow.draw(circle);
                renderWindow.display();

                sf::sleep(sf::seconds(0.1f));
        }

        return 0;
}

 

 

anything