cppAcademy
← Learning PathLESSON 18 / 25 · COMPUTATIONAL GEOMETRY · 45 MIN✕

Geometric Transformations

Transformations move a geometric object while preserving or predictably changing its structure. Translation shifts every point, rotation turns it around a center, reflection flips it across a line, and scaling changes its size. Applying the same point operation to every vertex transforms a polygon. The program demonstrates these operations independently on one point so their effects and formulas remain distinguishable.

Prerequisites: Vectors; Dot Product; projection; trigonometry.

Build the idea

  1. Translate and scale around a center

    Translation is P→P+T. Scaling about C is P→C+s(P−C), not simply sP unless C is the origin. A positive scale preserves orientation; a negative uniform scale in 2D rotates by 180 degrees as well as changing size, so it also preserves polygon orientation when nonzero. Scale zero collapses everything to C. Lengths scale by |s| and areas by s².

  2. Derive the rotation matrix

    A counterclockwise angle θ maps the x-unit vector to (cosθ,sinθ) and the y-unit vector to (−sinθ,cosθ). Linearity therefore maps (x,y) to (x cosθ−y sinθ,x sinθ+y cosθ). To rotate about C, subtract C first, rotate the displacement, then add C back. C++ trigonometric functions accept radians.

    Rθ(x,y)=(xcosθ−ysinθ,xsinθ+ycosθ)

  3. Reflect using a projection

    For reflection across the line through distinct A,B, project P to its perpendicular foot H. The reflected point is H+(H−P)=2H−P. The line is the perpendicular bisector of the segment joining the original and reflected points. If A=B no reflection line is defined; report that rather than dividing by a zero squared direction length.

  4. Trace the sample

    P=(2,1),C=(1,1),T=(3,−1), angle 90 degrees,scale 2. Translation gives (5,0). Rotation moves the displacement (1,0) to (0,1), giving (1,2). Scaling gives (3,1). Reflection across the x-axis gives (2,−1). These are four independent results from the original P, not a chained transformation.

  5. Compose with care

    Order matters: translating and then rotating usually differs from rotating and then translating. Repeated floating rotations accumulate error; keep the original coordinates and apply a composed transformation when possible. For exact 90-degree rotations on integer points, use (x,y)→(−y,x) directly. The long-double implementation supports arbitrary angles but prints approximate coordinates.

C++17 implementation

This is a complete program. Compile with C++17 and enter the input described below.

#include<iostream>
#include<cmath>
#include<iomanip>
struct Point{
    long double x,y;
    Point operator+(Point p)const{
        return {x+p.x,y+p.y};
    }
    Point operator-(Point p)const{
        return {x-p.x,y-p.y};
    }
    Point operator*(long double s)const{
        return {x*s,y*s};
    }
};
void print(Point p){
    std::cout<<p.x<<' '<<p.y<<'\n';
}
int main(){
    Point p,c,t,a,b;
    long double degrees,scale;
    std::cin>>p.x>>p.y>>c.x>>c.y>>t.x>>t.y>>degrees>>scale>>a.x>>a.y>>b.x>>b.y;
    std::cout<<std::fixed<<std::setprecision(6);
    print(p+t);
    // Work relative to C for both rotation and scaling, then translate back.
    Point v=p-c;
    long double angle=degrees*std::acos(-1.0L)/180;
    print(c+
        Point{v.x*std::cos(angle)-v.y*std::sin(angle),v.x*std::sin(angle)+v.y*std::cos(angle)});
    print(c+v*scale);
    Point d=b-a,w=p-a;
    long double length2=d.x*d.x+d.y*d.y;
    if(length2==0){
        std::cout<<"INVALID REFLECTION LINE\n";
        return 0;
    }
    Point foot=a+d*((w.x*d.x+w.y*d.y)/length2);
    print(foot*2-p);
}

Complexity analysis

O(1) time and auxiliary space for one point. Applying a fixed transformation to n vertices costs O(n); compute shared sine/cosine once rather than once per vertex.

Common mistakes and edge cases. Convert degrees to radians. Subtract an arbitrary center before rotating or scaling. Reflection reverses orientation; a nonzero uniform 2D scale does not, even when negative. Avoid repeatedly rotating already-rounded output. Reject a collapsed reflection line.

Example input and output

Read px py cx cy tx ty degrees scale ax ay bx by, finite values within magnitude 10^6. Print independently translated, rotated-about-C, scaled-about-C, and reflected-across-AB points to six decimals; invalid reflection lines are reported.

Input

2 1 1 1 3 -1 90 2 0 0 1 0

Output

5.000000 0.000000
1.000000 2.000000
3.000000 1.000000
2.000000 -1.000000

Subtracting the rotation center gives (1,0); its quarter-turn is (0,1), then adding C gives (1,2).

Practical applications

Use to normalize geometry, simulate motion, exploit symmetry and place polygons. Matrix multiplication composes linear transformations; homogeneous three-by-three matrices incorporate translation. For exact lattice rotations use integer formulas where available.

Check your understanding

How do you rotate P about an arbitrary center C?

Put it into practice

Apply two reflections across the same line and compare with the original point.

Show a hint

Keep full-precision values between transformations.

Further reading