What's the best way to implement a geometric shape class?

Hello,

I’m trying to make a class of a simple 2D object, with specialized functions to manipulate it. The goal in the end is to create many of these shapes that animate together. A simple version (just a rectangle) could be something like this:

class Shape
{
    public:
        Shape();
        void draw();

        ofVec2f position;
        ofPath shape;

        float width;
        float height;
};

void Shape::draw()
{
    float hw = width/2;
    float hh = height/2;

    shape.clear();
    shape.moveTo(position.x - hw, position.y - hh);
    shape.lineTo(position.x + hw, position.y - hh);
    shape.lineTo(position.x + hw, position.y + hh);
    shape.lineTo(position.x - hw, position.y + hh);
    shape.close();
    shape.draw();
}

If I want to create a method that rotates the object around its center of mass, what would be the best implementation?

ofPath has a rotate method but this can only be done through an axis that crosses the origin of the entire screen. A way around this is to couple rotate with translate so that the axis is in the center of the object, but since the goal is to have many of these objects will this slow the whole project down? Having to rotate and translate the projection for each object seems computationally heavy…

My idea is to perhaps create an array of vectors that add to the center position creating the vertices and then rotate these individually each time the rotate method is called. However this means that all vertices would have to be rotated for each shape rotation. Is there an optimal way of doing it? I have a feeling there is a simple workaround to this but I’m just not getting it… Any help would be appreciated!

1 Like

you can just have an ofNode in that class and call transformGL on it whenever you want to draw the path

So just to check if I’m doing this correctly, should I extend the ofNode class using customDraw() as follows?

class Shape : public ofNode
{
    public:
        Shape();
        void setWidth(float w);
        void setHeight(float h);
        void customDraw();

        float width;
        float height;

};

void Shape::customDraw()
{
	float hw = width/2;
	float hh = height/2;

	ofBeginShape();
		ofVertex(-hw, -hh);
		ofVertex( hw, -hh);
		ofVertex( hw,  hh);
		ofVertex(-hw,  hh);
	ofEndShape(OF_CLOSE);
}

Would it be acceptable to use ofPath instead inside the draw function?

yes, that should work, and yes you can and it’s indeed better to use ofPath instead of begin/endShape

Great! Thanks for pointing me in the right direction.