// File: 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
movq %rsp, %rbp
subq $0x100, %rsp            # imm = 0x100
movq %rdi, -0xc0(%rbp)
movq %rdi, %rax
movq %rax, -0xb8(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movsd %xmm0, -0x18(%rbp)
movsd %xmm1, -0x20(%rbp)
movsd %xmm2, -0x28(%rbp)
movb $0x0, -0x29(%rbp)
callq 0x8360
movsd -0x18(%rbp), %xmm0
movsd -0x20(%rbp), %xmm1
addsd %xmm1, %xmm0
movsd %xmm0, -0x38(%rbp)
movq -0x10(%rbp), %rsi
leaq -0x50(%rbp), %rdi
callq 0xb360
jmp 0xb08e
movabsq $0x3f847ae147ae147b, %rax # imm = 0x3F847AE147AE147B
movq %rax, -0x68(%rbp)
movsd -0x38(%rbp), %xmm0
movsd 0x20def(%rip), %xmm2    # 0x2be98
movaps %xmm0, %xmm1
subsd %xmm2, %xmm1
mulsd %xmm1, %xmm1
mulsd %xmm0, %xmm0
subsd %xmm1, %xmm0
callq 0x31f0
movsd %xmm0, -0x70(%rbp)
movsd -0x38(%rbp), %xmm0
movsd 0x1ff95(%rip), %xmm1    # 0x2b068
mulsd %xmm1, %xmm0
movsd -0x70(%rbp), %xmm1
addsd %xmm1, %xmm1
divsd %xmm1, %xmm0
callq 0x3080
cvttsd2si %xmm0, %eax
movl %eax, -0x74(%rbp)
movl -0x74(%rbp), %eax
movl %eax, -0xc8(%rbp)
movq -0x10(%rbp), %rdi
callq 0x3100
movl -0xc8(%rbp), %edi
movl %eax, %esi
callq 0xb4a0
movl %eax, -0xc4(%rbp)
jmp 0xb117
movl -0xc4(%rbp), %eax
movl %eax, -0x74(%rbp)
movsd -0x28(%rbp), %xmm0
movaps 0x20d84(%rip), %xmm1    # 0x2beb0
pand %xmm1, %xmm0
movsd 0x20d68(%rip), %xmm1    # 0x2bea0
ucomisd %xmm1, %xmm0
jbe 0xb174
movl -0x74(%rbp), %eax
shll $0x2, %eax
movl %eax, -0x74(%rbp)
jmp 0xb174
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0xb342
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x50(%rbp), %rdi
callq 0xb670
jmp 0xb342
movl $0x0, -0x78(%rbp)
movl -0x78(%rbp), %eax
cmpl -0x74(%rbp), %eax
jge 0xb313
cvtsi2sdl -0x78(%rbp), %xmm0
cvtsi2sdl -0x74(%rbp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x80(%rbp)
movsd -0x80(%rbp), %xmm0
leaq -0x50(%rbp), %rdi
callq 0xb4d0
movsd %xmm0, -0xd0(%rbp)
jmp 0xb1b2
movsd -0xd0(%rbp), %xmm0
movsd %xmm0, -0x88(%rbp)
movsd -0x18(%rbp), %xmm1
movsd -0x20(%rbp), %xmm0
movsd -0x88(%rbp), %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x90(%rbp)
movsd -0x90(%rbp), %xmm1
movsd %xmm1, -0xe8(%rbp)
movsd -0x80(%rbp), %xmm0
movsd %xmm0, -0xe0(%rbp)
movsd -0x28(%rbp), %xmm0
movsd -0x38(%rbp), %xmm2
callq 0xb640
movsd %xmm0, -0xd8(%rbp)
jmp 0xb21a
movsd -0xd8(%rbp), %xmm1
movsd -0xe0(%rbp), %xmm0
addsd %xmm1, %xmm0
addsd %xmm0, %xmm0
movsd 0x1fe0e(%rip), %xmm1    # 0x2b048
mulsd %xmm1, %xmm0
callq 0x3480
movaps %xmm0, %xmm1
movsd -0xe8(%rbp), %xmm0
mulsd %xmm1, %xmm0
movsd %xmm0, -0x98(%rbp)
movsd -0x90(%rbp), %xmm1
movsd %xmm1, -0x100(%rbp)
movsd -0x80(%rbp), %xmm0
movsd %xmm0, -0xf8(%rbp)
movsd -0x28(%rbp), %xmm0
movsd -0x38(%rbp), %xmm2
callq 0xb640
movsd %xmm0, -0xf0(%rbp)
jmp 0xb290
movsd -0xf0(%rbp), %xmm1
movsd -0xf8(%rbp), %xmm0
addsd %xmm1, %xmm0
addsd %xmm0, %xmm0
movsd 0x1fd98(%rip), %xmm1    # 0x2b048
mulsd %xmm1, %xmm0
callq 0x30a0
movaps %xmm0, %xmm1
movsd -0x100(%rbp), %xmm0
mulsd %xmm1, %xmm0
movsd %xmm0, -0xa0(%rbp)
movsd -0x98(%rbp), %xmm0
movsd -0xa0(%rbp), %xmm1
leaq -0xb0(%rbp), %rdi
callq 0x8470
jmp 0xb2ee
movq -0xc0(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
callq 0x8440
jmp 0xb303
jmp 0xb305
movl -0x78(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x78(%rbp)
jmp 0xb17b
movb $0x1, -0x29(%rbp)
leaq -0x50(%rbp), %rdi
callq 0xb670
testb $0x1, -0x29(%rbp)
jne 0xb332
movq -0xc0(%rbp), %rdi
callq 0x84c0
movq -0xb8(%rbp), %rax
addq $0x100, %rsp            # imm = 0x100
popq %rbp
retq
movq -0xc0(%rbp), %rdi
callq 0x84c0
movq -0x58(%rbp), %rdi
callq 0x3440
nopw (%rax,%rax)