// File: /workspace/github_cpp_makefile_star2_O1/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 $0x88, %rsp
movapd %xmm2, 0x70(%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, 0x20(%rsp)
movapd %xmm0, 0x10(%rsp)
movb (%rsi), %al
testb %al, %al
movq %rsi, 0x8(%rsp)
je 0x6ace
leaq 0x1(%rsi), %rcx
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
movl $0x100, %ebp            # imm = 0x100
movl %eax, %edx
movzbl %dl, %r13d
cmpl %r13d, %ebp
cmovgel %r13d, %ebp
cmpl %r13d, %esi
cmovgl %esi, %r13d
movb (%rcx), %dl
incq %rcx
movl %r13d, %esi
testb %dl, %dl
jne 0x6aae
jmp 0x6ad9
movl $0x100, %ebp            # imm = 0x100
movl $0xffffffff, %r13d      # imm = 0xFFFFFFFF
testb %al, %al
je 0x6b7d
subl %ebp, %r13d
xorps %xmm0, %xmm0
cvtsi2sd %r13d, %xmm0
movsd %xmm0, 0x30(%rsp)
movq 0x8(%rsp), %rcx
leaq 0x1(%rcx), %r14
leaq 0x10(%rsp), %r15
leaq 0x38(%rsp), %r12
testl %r13d, %r13d
jle 0x6b34
movzbl %al, %eax
subl %ebp, %eax
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
divsd 0x30(%rsp), %xmm0
movsd %xmm0, 0x38(%rsp)
movq 0x18(%rsp), %rsi
cmpq 0x20(%rsp), %rsi
je 0x6b5b
movsd %xmm0, (%rsi)
jmp 0x6b50
movq $0x0, 0x38(%rsp)
movq 0x18(%rsp), %rsi
cmpq 0x20(%rsp), %rsi
je 0x6b68
movq $0x0, (%rsi)
addq $0x8, %rsi
movq %rsi, 0x18(%rsp)
jmp 0x6b73
movq %r15, %rdi
movq %r12, %rdx
callq 0x6ddc
jmp 0x6b73
movq %r15, %rdi
movq %r12, %rdx
callq 0x6ddc
movb (%r14), %al
incq %r14
testb %al, %al
jne 0x6b05
movsd 0x50(%rsp), %xmm0
addsd 0x58(%rsp), %xmm0
movsd 0xe2ef(%rip), %xmm1     # 0x14e80
addsd %xmm0, %xmm1
mulsd %xmm1, %xmm1
movsd %xmm0, 0x48(%rsp)
mulsd %xmm0, %xmm0
subsd %xmm1, %xmm0
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jb 0x6bb7
sqrtsd %xmm0, %xmm0
jmp 0x6bbc
callq 0x31a0
movq 0x8(%rsp), %r15
movsd 0xd4af(%rip), %xmm1     # 0x14078
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 0xe28b(%rip), %xmm0     # 0x14e90
andpd 0x70(%rsp), %xmm0
leal (,%rsi,4), %ebp
ucomisd 0xe26e(%rip), %xmm0     # 0x14e88
cmovbel %esi, %ebp
testl %ebp, %ebp
jle 0x6d56
xorps %xmm0, %xmm0
cvtsi2sd %ebp, %xmm0
movsd %xmm0, 0x60(%rsp)
xorl %r15d, %r15d
leaq 0x38(%rsp), %r14
xorps %xmm0, %xmm0
cvtsi2sd %r15d, %xmm0
divsd 0x60(%rsp), %xmm0
movq 0x10(%rsp), %rcx
movq 0x18(%rsp), %rsi
subq %rcx, %rsi
sarq $0x3, %rsi
movq %rsi, %xmm1
punpckldq 0xe23a(%rip), %xmm1 # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0xe242(%rip), %xmm1     # 0x14eb0
movapd %xmm1, %xmm3
unpckhpd %xmm1, %xmm3            # xmm3 = xmm3[1],xmm1[1]
addsd %xmm1, %xmm3
mulsd %xmm0, %xmm3
cvttsd2si %xmm3, %edi
cmpl %esi, %edi
jge 0x6d82
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
movsd %xmm4, 0x30(%rsp)
movapd %xmm4, %xmm1
mulsd 0x70(%rsp), %xmm1
divsd 0x48(%rsp), %xmm1
addsd %xmm1, %xmm0
addsd %xmm0, %xmm0
mulsd 0xd35e(%rip), %xmm0     # 0x14048
movsd %xmm0, 0x68(%rsp)
callq 0x33c0
mulsd 0x30(%rsp), %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x68(%rsp), %xmm0
callq 0x3090
mulsd 0x30(%rsp), %xmm0
movsd 0x8(%rsp), %xmm1
movsd %xmm1, 0x38(%rsp)
movsd %xmm0, 0x40(%rsp)
movq 0x8(%rbx), %rsi
cmpq 0x10(%rbx), %rsi
je 0x6d3f
movupd 0x38(%rsp), %xmm0
movupd %xmm0, (%rsi)
addq $0x10, 0x8(%rbx)
jmp 0x6d4a
movq %rbx, %rdi
movq %r14, %rdx
callq 0x6796
incl %r15d
cmpl %r15d, %ebp
jne 0x6c3a
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x6d6d
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x3220
movq %rbx, %rax
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xe137(%rip), %rdi      # 0x14ec0
leaq 0xe149(%rip), %rsi      # 0x14ed9
leaq 0xe158(%rip), %rcx      # 0x14eef
movl $0x25, %edx
callq 0x3150
jmp 0x6da5
jmp 0x6da5
movq %rax, %r14
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x6dbf
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x3220
movq (%rbx), %rdi
testq %rdi, %rdi
je 0x6dd3
movq 0x10(%rbx), %rsi
subq %rdi, %rsi
callq 0x3220
movq %r14, %rdi
callq 0x3380
nop