// File: /workspace/github_cpp_makefile_star2_O1/Luthaf[P]zeopp/geometry.cc
// Function: findLineIntersections(Point, Point, Point, double)
pair<int, vector<Point> > findLineIntersections(Point p1, Point p2, Point circCenter, double rad){

  double tolerance = 0.00001; // Tolerance for determining whether two numbers are equal

  double a = (p2[0] - p1[0])*(p2[0] - p1[0]) + (p2[1] - p1[1])*(p2[1] - p1[1]) + (p2[2] - p1[2])*(p2[2] - p1[2]);
  double b = 2.0*((p2[0] - p1[0])*(p1[0] - circCenter[0]) + (p2[1] - p1[1])*(p1[1] - circCenter[1]) + (p2[2] - p1[2])*(p1[2] - circCenter[2]));
  double c = circCenter[0]*circCenter[0] + circCenter[1]*circCenter[1] + circCenter[2]*circCenter[2] 
    + p1[0]*p1[0] + p1[1]*p1[1] + p1[2]*p1[2] 
    - 2.0*(circCenter[0]*p1[0] +circCenter[1]*p1[1] + circCenter[2]*p1[2]) - rad*rad;

  double discriminant = b*b - 4.0*a*c;

  int numResults;
  vector<Point> results;

  if(abs(discriminant) < tolerance){
    // Discriminant is zero. Line is tangent and therefore only has one intersection
    numResults = 1;
    double u = (-b/(2.0*a));
    Point intersection = p1.add((p2.subtract(p1)).scale(u));
    results.push_back(intersection);
  }
  else if (discriminant < 0){
    //Disciminant is negative. No intersection between line and sphere.
    numResults = 0;
  }
  else{
    //Discriminant is positive. Two intersection points exist
    numResults = 2;

    double u1 = ((-b + sqrt(discriminant))/(2.0*a));
    Point intersection1 = p1.add((p2.subtract(p1)).scale(u1));
    results.push_back(intersection1);

    double u2 = ((-b - sqrt(discriminant))/(2.0*a));
    Point intersection2 = p1.add((p2.subtract(p1)).scale(u2));
    results.push_back(intersection2);
  }
  return pair<int, vector<Point> > (numResults, results);
}

// Assembly:
pushq %rbx
subq $0xb0, %rsp
movq %rdi, %rbx
movsd 0xc0(%rsp), %xmm7
movsd 0xc8(%rsp), %xmm6
movsd 0xd8(%rsp), %xmm10
movsd 0xe0(%rsp), %xmm8
subsd %xmm7, %xmm10
subsd %xmm6, %xmm8
movapd %xmm8, %xmm1
mulsd %xmm8, %xmm1
movapd %xmm10, %xmm2
mulsd %xmm10, %xmm2
addsd %xmm1, %xmm2
movsd 0xe8(%rsp), %xmm11
movsd 0xd0(%rsp), %xmm9
subsd %xmm9, %xmm11
movapd %xmm11, %xmm12
mulsd %xmm11, %xmm12
addsd %xmm2, %xmm12
movsd 0xf0(%rsp), %xmm1
movsd 0xf8(%rsp), %xmm3
movapd %xmm7, %xmm4
subsd %xmm1, %xmm4
movapd %xmm6, %xmm2
subsd %xmm3, %xmm2
mulsd %xmm8, %xmm2
mulsd %xmm10, %xmm4
addsd %xmm2, %xmm4
movsd 0x100(%rsp), %xmm2
movapd %xmm9, %xmm13
subsd %xmm2, %xmm13
mulsd %xmm11, %xmm13
addsd %xmm4, %xmm13
addsd %xmm13, %xmm13
movapd %xmm6, %xmm4
mulsd %xmm3, %xmm4
mulsd %xmm3, %xmm3
movapd %xmm1, %xmm5
mulsd %xmm1, %xmm5
addsd %xmm3, %xmm5
movapd %xmm2, %xmm3
mulsd %xmm2, %xmm3
addsd %xmm5, %xmm3
movapd %xmm7, %xmm5
mulsd %xmm7, %xmm5
addsd %xmm3, %xmm5
movapd %xmm6, %xmm3
mulsd %xmm6, %xmm3
addsd %xmm5, %xmm3
movapd %xmm9, %xmm5
mulsd %xmm9, %xmm5
addsd %xmm3, %xmm5
mulsd %xmm7, %xmm1
addsd %xmm4, %xmm1
mulsd %xmm9, %xmm2
addsd %xmm1, %xmm2
addsd %xmm2, %xmm2
subsd %xmm2, %xmm5
mulsd %xmm0, %xmm0
subsd %xmm0, %xmm5
movsd 0xd04b0(%rip), %xmm0    # 0x156f70
mulsd %xmm12, %xmm0
mulsd %xmm5, %xmm0
movapd %xmm13, %xmm2
mulsd %xmm13, %xmm2
addsd %xmm0, %xmm2
xorpd %xmm0, %xmm0
movapd %xmm0, (%rsp)
movq $0x0, 0x10(%rsp)
movapd 0xc859f(%rip), %xmm0    # 0x14f090
andpd %xmm2, %xmm0
movsd 0xcca7b(%rip), %xmm1    # 0x153578
ucomisd %xmm0, %xmm1
jbe 0x86b6e
xorpd 0xccaa4(%rip), %xmm13   # 0x1535b0
addsd %xmm12, %xmm12
divsd %xmm12, %xmm13
mulsd %xmm13, %xmm10
mulsd %xmm13, %xmm8
mulsd %xmm13, %xmm11
addsd %xmm10, %xmm7
addsd %xmm8, %xmm6
addsd %xmm11, %xmm9
movsd %xmm7, 0x48(%rsp)
movsd %xmm6, 0x50(%rsp)
movsd %xmm9, 0x58(%rsp)
movq 0x8(%rsp), %rsi
cmpq 0x10(%rsp), %rsi
je 0x86bcc
movq 0x58(%rsp), %rax
movq %rax, 0x10(%rsi)
movupd 0x48(%rsp), %xmm0
movupd %xmm0, (%rsi)
addq $0x18, 0x8(%rsp)
jmp 0x86bd9
movapd %xmm13, 0x70(%rsp)
movsd %xmm11, 0x60(%rsp)
movsd %xmm10, 0x28(%rsp)
movsd %xmm9, 0x68(%rsp)
movsd %xmm8, 0x30(%rsp)
movsd %xmm7, 0x38(%rsp)
movsd %xmm6, 0x40(%rsp)
xorl %eax, %eax
xorpd %xmm0, %xmm0
ucomisd %xmm2, %xmm0
ja 0x86d57
movsd %xmm12, 0x20(%rsp)
ucomisd %xmm0, %xmm2
movapd %xmm2, 0xa0(%rsp)
jb 0x86be3
xorps %xmm0, %xmm0
sqrtsd %xmm2, %xmm0
jmp 0x86bec
movq %rsp, %rdi
leaq 0x48(%rsp), %rdx
callq 0x3012c
movl $0x1, %eax
jmp 0x86d57
movapd %xmm2, %xmm0
callq 0x4350
movsd 0x30(%rsp), %xmm2
movsd 0x28(%rsp), %xmm1
movsd 0x20(%rsp), %xmm3
addsd %xmm3, %xmm3
subsd 0x70(%rsp), %xmm0
movsd %xmm3, 0x20(%rsp)
divsd %xmm3, %xmm0
mulsd %xmm0, %xmm1
mulsd %xmm0, %xmm2
mulsd 0x60(%rsp), %xmm0
addsd 0x38(%rsp), %xmm1
addsd 0x40(%rsp), %xmm2
addsd 0x68(%rsp), %xmm0
movsd %xmm1, 0x48(%rsp)
movsd %xmm2, 0x50(%rsp)
movsd %xmm0, 0x58(%rsp)
movq 0x8(%rsp), %rsi
cmpq 0x10(%rsp), %rsi
je 0x86c6b
movq 0x58(%rsp), %rax
movq %rax, 0x10(%rsi)
movupd 0x48(%rsp), %xmm0
movupd %xmm0, (%rsi)
addq $0x18, 0x8(%rsp)
jmp 0x86c78
movq %rsp, %rdi
leaq 0x48(%rsp), %rdx
callq 0x3012c
movapd 0x70(%rsp), %xmm0
xorpd 0xcc92a(%rip), %xmm0    # 0x1535b0
movapd %xmm0, 0x70(%rsp)
xorpd %xmm0, %xmm0
movapd 0xa0(%rsp), %xmm1
ucomisd %xmm0, %xmm1
movapd %xmm1, %xmm0
jb 0x86ca9
sqrtsd %xmm0, %xmm0
jmp 0x86cae
callq 0x4350
movsd 0x40(%rsp), %xmm1
movsd 0x38(%rsp), %xmm2
movapd 0x70(%rsp), %xmm5
subsd %xmm0, %xmm5
divsd 0x20(%rsp), %xmm5
movsd 0x28(%rsp), %xmm3
mulsd %xmm5, %xmm3
movsd 0x30(%rsp), %xmm0
mulsd %xmm5, %xmm0
movsd 0x60(%rsp), %xmm4
mulsd %xmm5, %xmm4
addsd %xmm3, %xmm2
addsd %xmm0, %xmm1
movsd 0x68(%rsp), %xmm0
addsd %xmm4, %xmm0
movsd %xmm2, 0x88(%rsp)
movsd %xmm1, 0x90(%rsp)
movsd %xmm0, 0x98(%rsp)
movq 0x8(%rsp), %rsi
cmpq 0x10(%rsp), %rsi
je 0x86d42
movq 0x98(%rsp), %rax
movq %rax, 0x10(%rsi)
movupd 0x88(%rsp), %xmm0
movupd %xmm0, (%rsi)
addq $0x18, 0x8(%rsp)
jmp 0x86d52
movq %rsp, %rdi
leaq 0x88(%rsp), %rdx
callq 0x3012c
movl $0x2, %eax
movl %eax, (%rbx)
leaq 0x8(%rbx), %rdi
movq %rsp, %rsi
callq 0xe7f6
movq (%rsp), %rdi
testq %rdi, %rdi
je 0x86d7b
movq 0x10(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq %rbx, %rax
addq $0xb0, %rsp
popq %rbx
retq
jmp 0x86d8d
jmp 0x86d8d
jmp 0x86d8d
movq %rax, %rbx
movq (%rsp), %rdi
testq %rdi, %rdi
je 0x86da6
movq 0x10(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq %rbx, %rdi
callq 0x4780