// File: sundale[P]gcode/rs274ngc/nurbs_additional_functions.cc
// Function: nurbs_tangent(double, unsigned int, std::vector<CONTROL_POINT, std::allocator<CONTROL_POINT>>, std::vector<unsigned int, std::allocator<unsigned int>>)
PLANE_POINT nurbs_tangent(double u, unsigned int k,
                  std::vector<CONTROL_POINT> nurbs_control_points,
                  std::vector<unsigned int> knot_vector) {
    unsigned int n = nurbs_control_points.size() - 1;
    double umax = n - k + 2;
    double ulo = std::max(0.0, u-DU), uhi = std::min(umax, u+DU);
    PLANE_POINT P1 = nurbs_point(ulo, k, nurbs_control_points, knot_vector);
    PLANE_POINT P3 = nurbs_point(uhi, k, nurbs_control_points, knot_vector);
    PLANE_POINT r = {(P3.X - P1.X) / (uhi-ulo), (P3.Y - P1.Y) / (uhi-ulo)};
    unit(r);
    return r;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x160, %rsp            # imm = 0x160
movq %rsi, -0x128(%rbp)
movl %edi, %eax
movq -0x128(%rbp), %rdi
movq %rdi, -0x118(%rbp)
movq %rdx, -0x100(%rbp)
movsd %xmm0, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
movq %rdi, -0x28(%rbp)
movq %rdx, -0x30(%rbp)
callq 0x10bf0
decl %eax
movl %eax, -0x34(%rbp)
movl -0x34(%rbp), %eax
movl -0x1c(%rbp), %ecx
subl %ecx, %eax
addl $0x2, %eax
cvtsi2sd %rax, %xmm0
movsd %xmm0, -0x40(%rbp)
movq $0x0, -0x50(%rbp)
movsd -0x18(%rbp), %xmm0
movsd 0x100c3(%rip), %xmm1    # 0x7f870
movsd %xmm1, -0x120(%rbp)
subsd %xmm1, %xmm0
movsd %xmm0, -0x58(%rbp)
leaq -0x50(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0x10310
movsd -0x120(%rbp), %xmm1
movsd (%rax), %xmm0
movsd %xmm0, -0x48(%rbp)
movsd -0x18(%rbp), %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x68(%rbp)
leaq -0x40(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0x10d10
movq -0x118(%rbp), %rsi
movsd (%rax), %xmm0
movsd %xmm0, -0x60(%rbp)
movsd -0x48(%rbp), %xmm0
movsd %xmm0, -0x110(%rbp)
movl -0x1c(%rbp), %eax
movl %eax, -0x104(%rbp)
leaq -0x90(%rbp), %rdi
callq 0x10970
movq -0x100(%rbp), %rsi
leaq -0xa8(%rbp), %rdi
callq 0x10400
jmp 0x6f83e
movl -0x104(%rbp), %edi
movsd -0x110(%rbp), %xmm0
leaq -0x90(%rbp), %rsi
leaq -0xa8(%rbp), %rdx
callq 0x11440
movsd %xmm1, -0x138(%rbp)
movsd %xmm0, -0x130(%rbp)
jmp 0x6f871
movsd -0x138(%rbp), %xmm0
movsd -0x130(%rbp), %xmm1
movsd %xmm1, -0x78(%rbp)
movsd %xmm0, -0x70(%rbp)
leaq -0xa8(%rbp), %rdi
callq 0x12390
leaq -0x90(%rbp), %rdi
callq 0x123e0
movq -0x118(%rbp), %rsi
movsd -0x60(%rbp), %xmm0
movsd %xmm0, -0x148(%rbp)
movl -0x1c(%rbp), %eax
movl %eax, -0x13c(%rbp)
leaq -0xe0(%rbp), %rdi
callq 0x10970
movq -0x100(%rbp), %rsi
leaq -0xf8(%rbp), %rdi
callq 0x10400
jmp 0x6f8e1
movl -0x13c(%rbp), %edi
movsd -0x148(%rbp), %xmm0
leaq -0xe0(%rbp), %rsi
leaq -0xf8(%rbp), %rdx
callq 0x11440
movsd %xmm1, -0x158(%rbp)
movsd %xmm0, -0x150(%rbp)
jmp 0x6f914
movsd -0x158(%rbp), %xmm0
movsd -0x150(%rbp), %xmm1
movsd %xmm1, -0xc8(%rbp)
movsd %xmm0, -0xc0(%rbp)
leaq -0xf8(%rbp), %rdi
callq 0x12390
leaq -0xe0(%rbp), %rdi
callq 0x123e0
movsd -0xc8(%rbp), %xmm0
movsd -0x78(%rbp), %xmm1
subsd %xmm1, %xmm0
movsd -0x60(%rbp), %xmm1
movsd -0x48(%rbp), %xmm2
subsd %xmm2, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x10(%rbp)
movsd -0xc0(%rbp), %xmm0
movsd -0x70(%rbp), %xmm1
subsd %xmm1, %xmm0
movsd -0x60(%rbp), %xmm1
movsd -0x48(%rbp), %xmm2
subsd %xmm2, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x8(%rbp)
leaq -0x10(%rbp), %rdi
callq 0x6fa50
movsd -0x10(%rbp), %xmm0
movsd -0x8(%rbp), %xmm1
addq $0x160, %rsp            # imm = 0x160
popq %rbp
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb0(%rbp)
movl %eax, -0xb4(%rbp)
jmp 0x6f9ea
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb0(%rbp)
movl %eax, -0xb4(%rbp)
leaq -0xa8(%rbp), %rdi
callq 0x12390
leaq -0x90(%rbp), %rdi
callq 0x123e0
jmp 0x6fa36
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb0(%rbp)
movl %eax, -0xb4(%rbp)
jmp 0x6fa2a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb0(%rbp)
movl %eax, -0xb4(%rbp)
leaq -0xf8(%rbp), %rdi
callq 0x12390
leaq -0xe0(%rbp), %rdi
callq 0x123e0
movq -0xb0(%rbp), %rdi
callq 0x11f50
nopw %cs:(%rax,%rax)