// File: Luthaf[P]zeopp/OMS.cc
// Function: PlaneAngle(double*, double*, double*)
double PlaneAngle (double *Vector1, double *Vector2, double *Point)
{

	
	double Angle;

	// Elements for system resolution
	Matrix3d A;
	Vector3d b(Point[X_COORD], Point[Y_COORD], Point[Z_COORD]);
	Vector3d x;

	// Vectors defining the plane
	Vector3d v1(Vector1[X_COORD], Vector1[Y_COORD], Vector1[Z_COORD]);
	Vector3d v2(Vector2[X_COORD], Vector2[Y_COORD], Vector2[Z_COORD]);
	Vector3d n(Vector1[X_COORD], Vector1[Y_COORD], Vector1[Z_COORD]);
	
	n = n.cross(v2);

	/**** Fill the matrix ****/
	// Each column contains one vector, so the system solved returns the coordinates of the point in the system v1,v2,n
	for (int i = 0; i < DIM; i++)
		for (int j=0; j<DIM; j++)
			if (i == 0)			
				A(j,i) = v1(j);
			else if (i == 1) 
				A(j,i) = v2(j);
			else 	
				A(j,i) = n(j);

	//cout << "A\n" << A << "\n";

	/**** Compute the system ****/
	x = A.colPivHouseholderQr().solve(b);


	// Multiply normal by its coordinate
	n = x(Z_COORD)*n;


//cout << "Compute angle from " << n.norm() << " and " << b.norm() << "\n";
	Angle = asin(n.norm()/b.norm());
	
	/**** Return the value of the third element (lambda parameter of the normal) ****/
	return Angle;	



	// Elements for system resolution
	/*Vector3d VectorToPoint(Point[X_COORD], Point[Y_COORD], Point[Z_COORD]);

	// Variable for angle computation
	double Angle;
	double PVMod, PNMod;

	// Vectors defining the plane
	Vector3d v2(Vector2[X_COORD], Vector2[Y_COORD], Vector2[Z_COORD]);
	Vector3d PlaneNormal(Vector1[X_COORD], Vector1[Y_COORD], Vector1[Z_COORD]);
	
	PlaneNormal = PlaneNormal.cross(v2);

	PVMod = sqrt(	VectorToPoint(0)*VectorToPoint(0) + VectorToPoint(1)*VectorToPoint(1) + VectorToPoint(2)*VectorToPoint(2) );
	PNMod = sqrt(	PlaneNormal(0)*PlaneNormal(0) + PlaneNormal(1)*PlaneNormal(1) + PlaneNormal(2)*PlaneNormal(2) );


cout << "Compute angle from " << PNMod/PVMod << "\n";
	Angle = asin(PNMod/PVMod);


	return Angle;*/

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x220, %rsp            # imm = 0x220
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
leaq -0x68(%rbp), %rdi
callq 0x175210
movq -0x18(%rbp), %rsi
movq -0x18(%rbp), %rdx
addq $0x8, %rdx
movq -0x18(%rbp), %rcx
addq $0x10, %rcx
leaq -0x80(%rbp), %rdi
callq 0x174e70
leaq -0x98(%rbp), %rdi
callq 0x175230
movq -0x8(%rbp), %rsi
movq -0x8(%rbp), %rdx
addq $0x8, %rdx
movq -0x8(%rbp), %rcx
addq $0x10, %rcx
leaq -0xb0(%rbp), %rdi
callq 0x174e70
movq -0x10(%rbp), %rsi
movq -0x10(%rbp), %rdx
addq $0x8, %rdx
movq -0x10(%rbp), %rcx
addq $0x10, %rcx
leaq -0xc8(%rbp), %rdi
callq 0x174e70
movq -0x8(%rbp), %rsi
movq -0x8(%rbp), %rdx
addq $0x8, %rdx
movq -0x8(%rbp), %rcx
addq $0x10, %rcx
leaq -0xe0(%rbp), %rdi
callq 0x174e70
leaq -0xf8(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
leaq -0xc8(%rbp), %rdx
callq 0x174f00
leaq -0xe0(%rbp), %rdi
leaq -0xf8(%rbp), %rsi
callq 0x175150
movl $0x0, -0xfc(%rbp)
cmpl $0x3, -0xfc(%rbp)
jge 0x174681
movl $0x0, -0x100(%rbp)
cmpl $0x3, -0x100(%rbp)
jge 0x17466b
cmpl $0x0, -0xfc(%rbp)
jne 0x1745c4
movslq -0x100(%rbp), %rsi
leaq -0xb0(%rbp), %rdi
callq 0x175180
movsd (%rax), %xmm0
movsd %xmm0, -0x208(%rbp)
movslq -0x100(%rbp), %rsi
movslq -0xfc(%rbp), %rdx
leaq -0x68(%rbp), %rdi
callq 0x175250
movsd -0x208(%rbp), %xmm0
movsd %xmm0, (%rax)
jmp 0x174655
cmpl $0x1, -0xfc(%rbp)
jne 0x174611
movslq -0x100(%rbp), %rsi
leaq -0xc8(%rbp), %rdi
callq 0x175180
movsd (%rax), %xmm0
movsd %xmm0, -0x210(%rbp)
movslq -0x100(%rbp), %rsi
movslq -0xfc(%rbp), %rdx
leaq -0x68(%rbp), %rdi
callq 0x175250
movsd -0x210(%rbp), %xmm0
movsd %xmm0, (%rax)
jmp 0x174653
movslq -0x100(%rbp), %rsi
leaq -0xe0(%rbp), %rdi
callq 0x175180
movsd (%rax), %xmm0
movsd %xmm0, -0x218(%rbp)
movslq -0x100(%rbp), %rsi
movslq -0xfc(%rbp), %rdx
leaq -0x68(%rbp), %rdi
callq 0x175250
movsd -0x218(%rbp), %xmm0
movsd %xmm0, (%rax)
jmp 0x174655
jmp 0x174657
movl -0x100(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x100(%rbp)
jmp 0x174567
jmp 0x17466d
movl -0xfc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xfc(%rbp)
jmp 0x174550
leaq -0x1f0(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0x175310
leaq -0x1f0(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x175350
movq %rax, -0x110(%rbp)
movq %rdx, -0x108(%rbp)
leaq -0x98(%rbp), %rdi
leaq -0x110(%rbp), %rsi
callq 0x1753d0
leaq -0x98(%rbp), %rdi
movl $0x2, %esi
callq 0x175180
movq %rax, %rsi
leaq -0x200(%rbp), %rdi
leaq -0xe0(%rbp), %rdx
callq 0x175400
leaq -0xe0(%rbp), %rdi
leaq -0x200(%rbp), %rsi
callq 0x175440
leaq -0xe0(%rbp), %rdi
callq 0x175470
movsd %xmm0, -0x220(%rbp)
leaq -0x80(%rbp), %rdi
callq 0x175470
movaps %xmm0, %xmm1
movsd -0x220(%rbp), %xmm0
divsd %xmm1, %xmm0
callq 0x5830
movsd %xmm0, -0x20(%rbp)
movsd -0x20(%rbp), %xmm0
addq $0x220, %rsp            # imm = 0x220
popq %rbp
retq