import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.math.BigInteger;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.NavigableSet;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;
import java.util.Set;
import java.util.SortedSet;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeSet;
public class Main {
public static void main(String[] args) throws IOException{
StreamTokenizer cin = new StreamTokenizer(new BufferedInputStream(System.in));
InputReader in = new InputReader(System.in) ;
PrintWriter out = new PrintWriter(System.out) ;
int t = in.nextInt() ;
while(t-- > 0){
new Task().solve(in, out);
}
out.flush() ;
/*
Mat m = new Mat(1.8088715944 ,0.1911284056 ,3.0000000000) ;
out.println(m.num[0][2] + " " + m.num[1][2]);
out.flush();*/
}
}
class Task{
public void solve(InputReader in , PrintWriter out) throws IOException{
int n = in.nextInt() ;
Mat[] mat = new Mat[n] ;
for(int i = 0 ; i < n ; i++){
mat[i] = new Mat(in.nextDouble() , in.nextDouble() , in.nextDouble()) ;
}
Mat s = mat[n-1] ;
for(int i = n-2 ; i >= 0 ; i--){
s = s.mult(mat[i]) ;
}
double[][] a = new double[2][2] ;
double co = s.num[0][0] ;
double si = s.num[1][0] ;
a[0][0] = (1-co) ; a[0][1] = si ;
a[1][0] = -si ; a[1][1] = (1-co) ;
double A = a[0][0] * a[1][1] - a[0][1] * a[1][0] ;
double B = s.num[0][2] * a[1][1] - s.num[1][2] * a[0][1] ;
double C = a[0][0] * s.num[1][2] - a[1][0] * s.num[0][2] ;
DecimalFormat df = new DecimalFormat("0.0000000000");//这样为保持10位
out.print(df.format(B/A) + " ");
out.print(df.format(C/A) + " ");
double sita = Math.atan(s.num[1][0]/s.num[0][0]) ;
if(si > 0 && co > 0){}
else if(si > 0 && co < 0){
sita += Math.PI ;
}
else if(si < 0 && co > 0){
sita += 2.0*Math.PI ;
}
else if(si < 0 && co < 0){
sita += Math.PI ;
}
out.println(df.format(sita)) ;
}
}
class Mat{
double[][] num = new double[3][3] ;
Mat(double ox , double oy , double sita){
double c = Math.cos(sita) ;
double s = Math.sin(sita) ;
num[0][0] = c ; num[0][1] = -s ; num[0][2] = (1-c)*ox + s*oy ;
num[1][0] = s ; num[1][1] = c ; num[1][2] = (1-c)*oy - s*ox ;
num[2][0] = 0 ; num[2][1] = 0 ; num[2][2] = 1 ;
}
Mat(){
for(int i = 0 ; i < 3 ; i++) Arrays.fill(num[i], 0) ;
}
Mat mult(Mat o){
Mat s = new Mat() ;
for(int i = 0 ; i < 3 ; i++){
for(int j = 0 ; j < 3 ; j++){
for(int k = 0 ; k < 3 ; k++){
s.num[i][j] += num[i][k] * o.num[k][j] ;
}
}
}
return s ;
}
}
class InputReader{
public BufferedReader reader;
public StringTokenizer tokenizer;
public InputReader(InputStream stream){
reader = new BufferedReader(new InputStreamReader(stream), 32768) ;
tokenizer = null ;
}
public String next(){
while(tokenizer == null || ! tokenizer.hasMoreTokens()){
try{
tokenizer = new StringTokenizer(reader.readLine());
}catch (IOException e) {
throw new RuntimeException(e);
}
}
return tokenizer.nextToken();
}
public int nextInt(){
return Integer.parseInt(next());
}
public long nextLong(){
return Long.parseLong(next());
}
public double nextDouble(){
return Double.parseDouble(next());
}
}
hdu4998
最新推荐文章于 2018-05-06 16:55:42 发布