// File: /workspace/github_cpp_makefile_star2_O3/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, 0x58(%rsp)
movsd %xmm0, 0x50(%rsp)
movq %rdi, %rbx
xorl %eax, %eax
movq %rax, 0x10(%rdi)
xorpd %xmm0, %xmm0
movupd %xmm0, (%rdi)
movq %rax, 0x10(%rsp)
movapd %xmm0, (%rsp)
movq %rsi, 0x20(%rsp)
movb (%rsi), %al
testb %al, %al
je 0x68e5
movq 0x20(%rsp), %rdi
leaq 0x1(%rdi), %rcx
movl $0xffffffff, %r13d      # imm = 0xFFFFFFFF
movl $0x100, %ebp            # imm = 0x100
movl %eax, %edx
movl %r13d, %esi
movzbl %dl, %r13d
cmpl %r13d, %ebp
cmovgel %r13d, %ebp
cmpl %r13d, %esi
cmovgl %esi, %r13d
movb (%rcx), %dl
incq %rcx
testb %dl, %dl
jne 0x6832
subl %ebp, %r13d
xorps %xmm0, %xmm0
cvtsi2sd %r13d, %xmm0
movsd %xmm0, 0x60(%rsp)
leaq 0x1(%rdi), %r14
movq %rsp, %r15
leaq 0x30(%rsp), %r12
testl %r13d, %r13d
jle 0x689c
movzbl %al, %eax
subl %ebp, %eax
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
divsd 0x60(%rsp), %xmm0
movsd %xmm0, 0x30(%rsp)
movq 0x8(%rsp), %rsi
cmpq 0x10(%rsp), %rsi
je 0x68c3
movsd %xmm0, (%rsi)
jmp 0x68b8
movq $0x0, 0x30(%rsp)
movq 0x8(%rsp), %rsi
cmpq 0x10(%rsp), %rsi
je 0x68d0
movq $0x0, (%rsi)
addq $0x8, %rsi
movq %rsi, 0x8(%rsp)
jmp 0x68db
movq %r15, %rdi
movq %r12, %rdx
callq 0x6b46
jmp 0x68db
movq %r15, %rdi
movq %r12, %rdx
callq 0x6b46
movb (%r14), %al
incq %r14
testb %al, %al
jne 0x686d
movsd 0x50(%rsp), %xmm0
addsd 0x58(%rsp), %xmm0
movsd 0xe5bf(%rip), %xmm1     # 0x14eb8
addsd %xmm0, %xmm1
mulsd %xmm1, %xmm1
movsd %xmm0, 0x48(%rsp)
mulsd %xmm0, %xmm0
subsd %xmm1, %xmm0
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jb 0x691f
sqrtsd %xmm0, %xmm0
jmp 0x6924
callq 0x31a0
movq 0x20(%rsp), %r15
movsd 0xd7bf(%rip), %xmm1     # 0x140f0
mulsd 0x48(%rsp), %xmm1
addsd %xmm0, %xmm0
divsd %xmm0, %xmm1
movapd %xmm1, %xmm0
callq 0x3080
cvttsd2si %xmm0, %r14d
movq %r15, %rdi
callq 0x30e0
movq %rax, %rcx
leal (%rax,%r14), %esi
decl %esi
movl %esi, %eax
cltd
idivl %ecx
subl %edx, %esi
movapd 0xe563(%rip), %xmm0     # 0x14ed0
andpd 0x80(%rsp), %xmm0
leal (,%rsi,4), %ebp
ucomisd 0xe53b(%rip), %xmm0     # 0x14ec0
cmovbel %esi, %ebp
testl %ebp, %ebp
jle 0x6ac3
xorps %xmm0, %xmm0
cvtsi2sd %ebp, %xmm0
movsd %xmm0, 0x70(%rsp)
xorl %r15d, %r15d
leaq 0x30(%rsp), %r14
xorps %xmm0, %xmm0
cvtsi2sd %r15d, %xmm0
divsd 0x70(%rsp), %xmm0
movq (%rsp), %rcx
movq 0x8(%rsp), %rsi
subq %rcx, %rsi
sarq $0x3, %rsi
movq %rsi, %xmm1
punpckldq 0xe510(%rip), %xmm1 # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0xe518(%rip), %xmm1     # 0x14ef0
movapd %xmm1, %xmm3
unpckhpd %xmm1, %xmm3            # xmm3 = xmm3[1],xmm1[1]
addsd %xmm1, %xmm3
mulsd %xmm0, %xmm3
cvttsd2si %xmm3, %edi
cmpl %esi, %edi
jge 0x6aee
movslq %edi, %rax
movsd (%rcx,%rax,8), %xmm1
leal 0x1(%rdi), %eax
cltq
xorl %edx, %edx
divq %rsi
movsd (%rcx,%rdx,8), %xmm4
xorps %xmm2, %xmm2
cvtsi2sd %edi, %xmm2
subsd %xmm2, %xmm3
subsd %xmm1, %xmm4
mulsd %xmm3, %xmm4
addsd %xmm1, %xmm4
mulsd 0x58(%rsp), %xmm4
addsd 0x50(%rsp), %xmm4
movapd %xmm4, 0x60(%rsp)
movapd %xmm4, %xmm1
mulsd 0x80(%rsp), %xmm1
divsd 0x48(%rsp), %xmm1
addsd %xmm1, %xmm0
addsd %xmm0, %xmm0
mulsd 0xd669(%rip), %xmm0     # 0x140c0
movsd %xmm0, 0x78(%rsp)
callq 0x33c0
movapd %xmm0, 0x20(%rsp)
movsd 0x78(%rsp), %xmm0
callq 0x3090
movapd 0x20(%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, 0x30(%rsp)
movq 0x8(%rbx), %rsi
cmpq 0x10(%rbx), %rsi
je 0x6aac
movapd 0x30(%rsp), %xmm0
movupd %xmm0, (%rsi)
addq $0x10, 0x8(%rbx)
jmp 0x6ab7
movq %rbx, %rdi
movq %r14, %rdx
callq 0x650a
incl %r15d
cmpl %r15d, %ebp
jne 0x69a5
movq (%rsp), %rdi
testq %rdi, %rdi
je 0x6ad9
movq 0x10(%rsp), %rsi
subq %rdi, %rsi
callq 0x3220
movq %rbx, %rax
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xe40b(%rip), %rdi      # 0x14f00
leaq 0xe41d(%rip), %rsi      # 0x14f19
leaq 0xe42c(%rip), %rcx      # 0x14f2f
movl $0x25, %edx
callq 0x3150
jmp 0x6b11
jmp 0x6b11
movq %rax, %r14
movq (%rsp), %rdi
testq %rdi, %rdi
je 0x6b2a
movq 0x10(%rsp), %rsi
subq %rdi, %rsi
callq 0x3220
movq (%rbx), %rdi
testq %rdi, %rdi
je 0x6b3e
movq 0x10(%rbx), %rsi
subq %rdi, %rsi
callq 0x3220
movq %r14, %rdi
callq 0x3380