using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static string InputPattern = "InputX";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("2");
WillReturn.Add("5 0");
WillReturn.Add("-5 0");
WillReturn.Add("-1 3");
WillReturn.Add("2 4");
//1 -3
//-2 -4
}
else if (InputPattern == "Input2") {
WillReturn.Add("4");
WillReturn.Add("4 4");
WillReturn.Add("12 10");
WillReturn.Add("12 4");
WillReturn.Add("8 7");
WillReturn.Add("-4 -2");
WillReturn.Add("100 10");
//1.4 -4.8
//0 0
//-15 0
//75.4 -52.8
}
else if (InputPattern == "Input3") {
WillReturn.Add("10");
WillReturn.Add("-40336 -25353");
WillReturn.Add("25518 98473");
WillReturn.Add("-66200 57666");
WillReturn.Add("23235 -64774");
WillReturn.Add("56870 -67151");
WillReturn.Add("-99509 73639");
WillReturn.Add("39965 -61027");
WillReturn.Add("-54385 -34598");
WillReturn.Add("-57063 14129");
WillReturn.Add("63186 -88708");
WillReturn.Add("88770 85106");
WillReturn.Add("-92520 69200");
//-8970.87249328212 61817.21737274555
//-75079.28924877638 -74637.35403870217
//-61384.55754506934 -105449.9760881721
//-10508.55928227892 98726.04733711783
//-63915.43362406853 -87648.93490309674
//-84883.41976667292 8062.914405771756
//-43119.58914921946 33307.21406245974
//-77451.63868397648 -121148.543178062
//88022.56926540422 -62121.98851386775
//-11146.07084342446 90471.08392051774
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
struct ABInfoDef
{
internal double A;
internal double B;
}
struct VectorDef
{
internal double X;
internal double Y;
}
static void Main()
{
List<string> InputList = GetInputList();
double[] wkArr = { };
Action<string> SplitAct = pStr =>
wkArr = pStr.Split(' ').Select(pX => double.Parse(pX)).ToArray();
SplitAct(InputList[1]);
double X1 = wkArr[0];
double Y1 = wkArr[1];
SplitAct(InputList[2]);
double X2 = wkArr[0];
double Y2 = wkArr[1];
var ABInfoList = new List<ABInfoDef>();
foreach (string EachStr in InputList.Skip(3)) {
SplitAct(EachStr);
ABInfoDef WillAdd;
WillAdd.A = wkArr[0];
WillAdd.B = wkArr[1];
ABInfoList.Add(WillAdd);
}
// 両目の中点の座標
VectorDef MidPos;
MidPos.X = (X1 + X2) / 2;
MidPos.Y = (Y1 + Y2) / 2;
// 両目の中点が原点になるように、平行移動
X1 -= MidPos.X;
X2 -= MidPos.X;
Y1 -= MidPos.Y;
Y2 -= MidPos.Y;
// Eを求める
double E = Math.Sqrt(X1 * X1 + Y1 * Y1);
double KaitenRad = DeriveKaitenRad(E, X2, Y2);
// 逆回転に変換
KaitenRad = Math.PI * 2 - KaitenRad;
foreach (ABInfoDef EachABInfo in ABInfoList) {
double X = EachABInfo.A;
double Y = EachABInfo.B;
X -= MidPos.X;
Y -= MidPos.Y;
VectorDef CurrPos;
CurrPos.X = X;
CurrPos.Y = Y;
VectorDef Result = Exec1JiHenkan(CurrPos, Math.Sin(KaitenRad), Math.Cos(KaitenRad));
decimal DecX = (decimal)Result.X;
decimal DecY = (decimal)Result.Y;
Console.WriteLine("{0} {1}", DecX, DecY);
}
}
// (E,0)を何度回転したら(X2,Y2)になるかを返す
static double DeriveKaitenRad(double pE, double pX2, double pY2)
{
// Y座標がマイナスなら、原点と対称移動
bool Moved = false;
if (pY2 < 0) {
Moved = true;
pX2 *= -1;
pY2 *= -1;
}
double Rad = Math.Acos(pX2 / pE);
// 原点と対称移動してたら、回転角を180度追加
if (Moved) Rad += Math.PI;
return Rad;
}
// ベクトルとSinとCosを引数として、回転したベクトルを返す
static VectorDef Exec1JiHenkan(VectorDef pPos, double pSin, double pCos)
{
VectorDef WillReturn;
WillReturn.X = pCos * pPos.X + pPos.Y * -pSin;
WillReturn.Y = pSin * pPos.X + pPos.Y * pCos;
return WillReturn;
}
}