AOJ 0081 A Symmetric Point

[問題]
AOJ 0081 「A Symmetric Point」
1つの直線と1つの点が与えられる。与えられた点と線対称な点を答える。

[参考元]
コンピュータグラフィックス

座標変換は5個。
1. 平行移動
2. 拡大・縮小
3. 回転
4. 鏡映
5. スキュー

P1を原点に平行移動する量をtとする。
直線P1-P2とx座標の正方向の角度をθとする。

1. 点Qをt平行移動
2. 点Qを-θ回転移動
3. 点Qをx軸に対して鏡映
4. 点Qをθ回転移動
5. 点Qを-t平行移動

#include <iostream>
#include <iomanip>
#include <cmath>

using namespace std;

// x軸方向にtx, y軸方向にtyだけ平行移動
void translation(double tx, double ty, double &x, double &y) 
{
    x += tx;
    y += ty;
}

// thetaだけ回転
void rotation(double theta, double &x, double &y) 
{
    double tx = x;
    double ty = y;

    x = cos(theta) * tx - sin(theta) * ty;
    y = sin(theta) * tx + cos(theta) * ty;
}

// x軸に関する鏡映
void x_reflection(double &x, double &y) 
{
    y *= -1;
}


int main()
{
    double x1, y1, x2, y2, xq, yq;
    char ch;

    cout << setiosflags(ios::fixed) << setprecision(6);
    while (cin >> x1 >> ch >> y1 >> ch >> x2 >> ch >> y2
           >> ch >> xq >> ch >> yq) {
        double theta = atan((y2 - y1) / (x2 - x1));

        translation(-x1, -y1, xq, yq);
        rotation(-theta, xq, yq);
        x_reflection(xq, yq);
        rotation(theta, xq, yq);
        translation(x1, y1, xq, yq);
        
        cout << xq << " " << yq << endl;
    }
}