// File: /workspace/github_cpp_makefile_star2_O2/hzeller[P]gcode-multi-shell-extrude/rotational-polygon.cc
// Function: RotationalPolygon(char const*, double, double, double)
Polygon RotationalPolygon(const char *fun_init, double inner_radius,
			  double thread_depth, double twist) {
  Polygon result;
  const double max_r = inner_radius + thread_depth;
  PolarFunction fun(fun_init);
  const double max_error = 0.01;  // millimeter; maximum error to tolerate
  // Maximum lenght of one edge of our cylinder, that should not differ more
  // than max_error in the middle. Half a segment is a nice perpendicular
  // triangle
  const double half_segment = sqrt((max_r*max_r)
                                   - (max_r - max_error)*(max_r - max_error));
  int faces = ceil((2 * M_PI * max_r) / (2 * half_segment));
  faces = quantize_up(faces, strlen(fun_init));   // same sampling per letter.
  if (fabs(twist) > 0.05) {
    faces *= 4;  // when twisting, we do more. TODO: calculate better.
  }
  for (int f = 0; f < faces; ++f) {
    const double angle = 1.0 * f / faces;
    double pol_value = fun.value(angle);
    const double r = inner_radius + thread_depth * pol_value;
    const double x = r * cos((angle + AngleTwist(twist, r, max_r)) * 2 * M_PI);
    const double y = r * sin((angle + AngleTwist(twist, r, max_r)) * 2 * M_PI);
    result.push_back(Vector2D(x, y));
  }
  return result;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x98, %rsp
movapd %xmm2, 0x80(%rsp)
movsd %xmm1, 0x18(%rsp)
movsd %xmm0, 0x10(%rsp)
movq %rsi, %r14
movq %rdi, %rbx
xorps %xmm0, %xmm0
andq $0x0, 0x10(%rdi)
movups %xmm0, (%rdi)
andq $0x0, 0x40(%rsp)
movaps %xmm0, 0x30(%rsp)
movl $0x100, %ebp            # imm = 0x100
pushq $-0x1
popq %r13
movq %rsi, %rax
movzbl (%rax), %ecx
testl %ecx, %ecx
je 0x5e4e
cmpl %ecx, %ebp
cmovgel %ecx, %ebp
cmpl %ecx, %r13d
cmovlel %ecx, %r13d
incq %rax
jmp 0x5e36
movsd 0x10(%rsp), %xmm0
subl %ebp, %r13d
cvtsi2sd %r13d, %xmm1
movsd %xmm1, 0x60(%rsp)
addsd 0x18(%rsp), %xmm0
movsd %xmm0, 0x8(%rsp)
leaq 0x30(%rsp), %r15
leaq 0x20(%rsp), %r12
movq %r14, 0x50(%rsp)
movzbl (%r14), %eax
testl %eax, %eax
je 0x5ebf
testl %r13d, %r13d
jle 0x5ea9
subl %ebp, %eax
cvtsi2sd %eax, %xmm0
divsd 0x60(%rsp), %xmm0
movsd %xmm0, 0x20(%rsp)
movq %r15, %rdi
movq %r12, %rsi
callq 0x60cc
jmp 0x5eba
andq $0x0, 0x20(%rsp)
movq %r15, %rdi
movq %r12, %rsi
callq 0x60cc
incq %r14
jmp 0x5e7d
movsd 0xd001(%rip), %xmm1     # 0x12ec8
movsd 0x8(%rsp), %xmm0
addsd %xmm0, %xmm1
mulsd %xmm1, %xmm1
mulsd %xmm0, %xmm0
subsd %xmm1, %xmm0
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jb 0x5eed
sqrtsd %xmm0, %xmm0
jmp 0x5ef2
callq 0x31b0
movsd 0xc1de(%rip), %xmm1     # 0x120d8
mulsd 0x8(%rsp), %xmm1
addsd %xmm0, %xmm0
divsd %xmm0, %xmm1
movapd %xmm1, %xmm0
callq 0x3080
cvttsd2si %xmm0, %r14d
movq 0x50(%rsp), %rdi
callq 0x30e0
movq %rax, %rcx
leal (%rax,%r14), %esi
decl %esi
movl %esi, %eax
cltd
idivl %ecx
subl %edx, %esi
movapd 0xcfa8(%rip), %xmm0     # 0x12ee0
andpd 0x80(%rsp), %xmm0
ucomisd 0xcf87(%rip), %xmm0     # 0x12ed0
leal (,%rsi,4), %ebp
cmovbel %esi, %ebp
cvtsi2sd %ebp, %xmm0
movsd %xmm0, 0x70(%rsp)
xorl %r15d, %r15d
testl %ebp, %ebp
cmovlel %r15d, %ebp
leaq 0x20(%rsp), %r14
cmpl %r15d, %ebp
je 0x606e
cvtsi2sd %r15d, %xmm0
divsd 0x70(%rsp), %xmm0
movq 0x30(%rsp), %rcx
movq 0x38(%rsp), %rsi
subq %rcx, %rsi
sarq $0x3, %rsi
movq %rsi, %xmm1
punpckldq 0xcf53(%rip), %xmm1 # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0xcf5b(%rip), %xmm1     # 0x12f00
movapd %xmm1, %xmm3
unpckhpd %xmm1, %xmm3            # xmm3 = xmm3[1],xmm1[1]
addsd %xmm1, %xmm3
mulsd %xmm0, %xmm3
cvttsd2si %xmm3, %edi
cmpl %esi, %edi
jge 0x608d
movslq %edi, %rax
movsd (%rcx,%rax,8), %xmm1
leal 0x1(%rdi), %eax
cltq
xorl %edx, %edx
divq %rsi
movsd (%rcx,%rdx,8), %xmm4
cvtsi2sd %edi, %xmm2
subsd %xmm2, %xmm3
subsd %xmm1, %xmm4
mulsd %xmm3, %xmm4
addsd %xmm1, %xmm4
mulsd 0x18(%rsp), %xmm4
addsd 0x10(%rsp), %xmm4
movapd %xmm4, 0x60(%rsp)
movapd %xmm4, %xmm1
mulsd 0x80(%rsp), %xmm1
divsd 0x8(%rsp), %xmm1
addsd %xmm1, %xmm0
addsd %xmm0, %xmm0
mulsd 0xc087(%rip), %xmm0     # 0x120a8
movsd %xmm0, 0x78(%rsp)
callq 0x33d0
movapd %xmm0, 0x50(%rsp)
movsd 0x78(%rsp), %xmm0
callq 0x3090
movapd 0x50(%rsp), %xmm1
unpcklpd %xmm0, %xmm1            # xmm1 = xmm1[0],xmm0[0]
movapd 0x60(%rsp), %xmm0
unpcklpd %xmm0, %xmm0            # xmm0 = xmm0[0,0]
mulpd %xmm1, %xmm0
movapd %xmm0, 0x20(%rsp)
movq %rbx, %rdi
movq %r14, %rsi
callq 0x5b92
incl %r15d
jmp 0x5f6b
leaq 0x30(%rsp), %rdi
callq 0x6260
movq %rbx, %rax
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xce7c(%rip), %rdi      # 0x12f10
leaq 0xce8e(%rip), %rsi      # 0x12f29
leaq 0xce9d(%rip), %rcx      # 0x12f3f
pushq $0x25
popq %rdx
callq 0x3160
jmp 0x60ae
jmp 0x60ae
movq %rax, %r14
leaq 0x30(%rsp), %rdi
callq 0x6260
movq %rbx, %rdi
callq 0x5b22
movq %r14, %rdi
callq 0x33a0
nop