Basic transformations
About the code
Shapes
// define the shape
Vec2f shape[] =
{
{-20, 20}, {-20, -20}, {30, 20}
};
And we draw it as if the origin is at the center of the screen
void drawShape(Vec2f* points, int nbPoints, Color color)
{
for (int i = 0; i < nbPoints; i++)
{
int next = (i + 1) % nbPoints;
gfx.line(points[i].x + SCREEN_WIDTH / 2,
points[i].y + SCREEN_HEIGHT / 2,
points[next].x + SCREEN_WIDTH / 2,
points[next].y + SCREEN_HEIGHT / 2,
color);
}
}
Download source code
Download executable for Windows
And here is the result:
Translation
void translateShape(Vec2f* points, int nbPoints, Vec2f transVector)
{
for (int i = 0; i < nbPoints; i++)
points[i] += transVector;
}
And in our main loop we will make a copy of our shape, apply the transformation, then draw it:
while (sys.isQuitRequested() == false)
{
gfx.clearScreen(Color(0, 0, 0, SDL_ALPHA_OPAQUE));
drawShape(shape, 3, Color(0, 255, 255));
// copy shape
Vec2f shape2[3];
for (int i = 0; i < 3; i++)
shape2[i] = shape[i];
// translate and draw
translateShape(shape2, 3, Vec2f(150, 75));
drawShape(shape2, 3, Color(255, 0, 0));
gfx.render();
sys.wait(20);
sys.processEvents();
}
Download source code
Download executable for Windows
Scaling
void Vec2f::scale(const Vec2f& s)
{
x *= s.x;
y *= s.y;
}
Now if we modify our main loop to use this function on the copy of our shape
void scaleShape(Vec2f* points, int nbPoints, Vec2f scaleVector)
{
for (int i = 0; i < nbPoints; i++)
points[i].scale(scaleVector);
}
[...]
while (sys.isQuitRequested() == false)
{
gfx.clearScreen(Color(0, 0, 0, SDL_ALPHA_OPAQUE));
drawShape(shape, 3, Color(0, 255, 255));
// copy shape
Vec2f shape2[3];
for (int i = 0; i < 3; i++)
shape2[i] = shape[i];
// scale and draw
scaleShape(shape2, 3, Vec2f(6, 3));
drawShape(shape2, 3, Color(255, 0, 0));
Download source code
Download executable for Windows
We get this:
// scale and draw
scaleShape(shape2, 3, Vec2f(-6, 3));
drawShape(shape2, 3, Color(255, 0, 0));
Download source code
Download executable for Windows
// scale and draw
scaleShape(shape2, 3, Vec2f(-6, -3));
drawShape(shape2, 3, Color(255, 0, 0));
Download source code
Download executable for Windows
Rotation
newX = x * cos(angle) - y * sin(angle);
newY = x * sin(angle) + y * cos(angle);
We can add that as a new function in our Vec2f class:
void Vec2f::rotate(const float angle)
{
float co = cos(angle);
float si = sin(angle);
float newX = x * co - y * si;
float newY = x * si + y * co;
x = newX;
y = newY;
}
Now let's test that with our shape
void rotateShape(Vec2f* points, int nbPoints, float angle)
{
for (int i = 0; i < nbPoints; i++)
points[i].rotate(angle);
}
[...]
while (sys.isQuitRequested() == false)
{
gfx.clearScreen(Color(0, 0, 0, SDL_ALPHA_OPAQUE));
drawShape(shape, 3, Color(0, 255, 255));
// copy shape
Vec2f shape2[3];
for (int i = 0; i < 3; i++)
shape2[i] = shape[i];
// rotate and draw
rotateShape(shape2, 3, DEG_TO_RAD(30));
drawShape(shape2, 3, Color(255, 0, 0));
Download source code
Download executable for Windows
And this is what we see:
Combining transformations
while (sys.isQuitRequested() == false)
{
gfx.clearScreen(Color(0, 0, 0, SDL_ALPHA_OPAQUE));
drawShape(shape, 3, Color(0, 255, 255));
// copy shape
Vec2f shape2[3];
for (int i = 0; i < 3; i++)
shape2[i] = shape[i];
// transform and draw
scaleShape(shape2, 3, Vec2f(-2, 1));
translateShape(shape2, 3, Vec2f(100, 50));
drawShape(shape2, 3, Color(0, 255, 0));
// copy shape
Vec2f shape3[3];
for (int i = 0; i < 3; i++)
shape3[i] = shape[i];
// transform and draw
translateShape(shape3, 3, Vec2f(100, 50));
scaleShape(shape3, 3, Vec2f(-2, 1));
drawShape(shape3, 3, Color(255, 0, 0));
Download source code
Download executable for Windows
And this is what we get:
float angle = 0;
// wait until we quit
while (sys.isQuitRequested() == false)
{
gfx.clearScreen(Color(0, 0, 0, SDL_ALPHA_OPAQUE));
drawShape(shape, 3, Color(0, 255, 255));
// copy shape
Vec2f shape2[3];
for (int i = 0; i < 3; i++)
shape2[i] = shape[i];
// transform and draw
rotateShape(shape2, 3, DEG_TO_RAD(angle));
translateShape(shape2, 3, Vec2f(150, 0));
drawShape(shape2, 3, Color(0, 255, 0));
// copy shape
Vec2f shape3[3];
for (int i = 0; i < 3; i++)
shape3[i] = shape[i];
// transform and draw
translateShape(shape3, 3, Vec2f(150, 0));
rotateShape(shape3, 3, DEG_TO_RAD(angle));
drawShape(shape3, 3, Color(255, 0, 0));
angle += 1;
Download source code
Download executable for Windows
Changing the center of rotation
void drawShapeLeft(Vec2f* points, int nbPoints, Color color)
{
for (int i = 0; i < nbPoints; i++)
{
int next = (i + 1) % nbPoints;
gfx.line(points[i].x + SCREEN_WIDTH / 3,
points[i].y + SCREEN_HEIGHT / 2,
points[next].x + SCREEN_WIDTH / 3,
points[next].y + SCREEN_HEIGHT / 2,
color);
}
}
void drawShapeRight(Vec2f* points, int nbPoints, Color color)
{
for (int i = 0; i < nbPoints; i++)
{
int next = (i + 1) % nbPoints;
gfx.line(points[i].x + SCREEN_WIDTH * 2 / 3,
points[i].y + SCREEN_HEIGHT / 2,
points[next].x + SCREEN_WIDTH * 2 / 3,
points[next].y + SCREEN_HEIGHT / 2,
color);
}
}
void translateShape(Vec2f* points, int nbPoints, Vec2f transVector)
{
for (int i = 0; i < nbPoints; i++)
points[i] += transVector;
}
void scaleShape(Vec2f* points, int nbPoints, Vec2f scaleVector)
{
for (int i = 0; i < nbPoints; i++)
points[i].scale(scaleVector);
}
void rotateShape(Vec2f* points, int nbPoints, float angle)
{
for (int i = 0; i < nbPoints; i++)
points[i].rotate(angle);
}
int main(int argc, char* argv[])
{
// init the window
gfx.init("2D Transforms 9", SCREEN_WIDTH, SCREEN_HEIGHT);
gfx.init2D();
// define the shape
Vec2f shape[] =
{
{-20, 20}, {-20, -20}, {30, 20}
};
float angle = 0;
// wait until we quit
while (sys.isQuitRequested() == false)
{
gfx.clearScreen(Color(0, 0, 0, SDL_ALPHA_OPAQUE));
drawShapeLeft(shape, 3, Color(0, 255, 255));
drawShapeRight(shape, 3, Color(0, 255, 255));
// copy shape
Vec2f shape2[3];
for (int i = 0; i < 3; i++)
shape2[i] = shape[i];
// transform and draw
rotateShape(shape2, 3, DEG_TO_RAD(angle));
drawShapeLeft(shape2, 3, Color(0, 255, 0));
// copy shape
Vec2f shape3[3];
for (int i = 0; i < 3; i++)
shape3[i] = shape[i];
// transform and draw
translateShape(shape3, 3, -shape[0]);
rotateShape(shape3, 3, DEG_TO_RAD(angle));
translateShape(shape3, 3, shape[0]);
drawShapeRight(shape3, 3, Color(255, 0, 0));
angle += 1;
gfx.render();
sys.wait(20);
sys.processEvents();
}
gfx.quit();
return EXIT_SUCCESS;
}
Download source code
Download executable for Windows
Links