user: 请将这段汇编代码片段转换成等效的C代码：

```asm
<projectPoint_double>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  push   %rbx
  sub    $0xa8,%rsp
  mov    %rdi,-0x88(%rbp)
  mov    %rsi,-0x90(%rbp)
  mov    %rdx,-0x98(%rbp)
  mov    %rcx,-0xa0(%rbp)
  mov    %r8,-0xa8(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x18(%rbp)
  xor    %eax,%eax
  mov    -0x98(%rbp),%rax
  movsd  (%rax),%xmm0
  mov    -0x90(%rbp),%rax
  movsd  (%rax),%xmm1
  subsd  %xmm1,%xmm0
  movsd  %xmm0,-0x70(%rbp)
  mov    -0x98(%rbp),%rax
  add    $0x8,%rax
  movsd  (%rax),%xmm0
  mov    -0x90(%rbp),%rax
  add    $0x8,%rax
  movsd  (%rax),%xmm1
  subsd  %xmm1,%xmm0
  movsd  %xmm0,-0x68(%rbp)
  mov    -0x98(%rbp),%rax
  add    $0x10,%rax
  movsd  (%rax),%xmm0
  mov    -0x90(%rbp),%rax
  add    $0x10,%rax
  movsd  (%rax),%xmm1
  subsd  %xmm1,%xmm0
  movsd  %xmm0,-0x60(%rbp)
  mov    -0xa0(%rbp),%rax
  movsd  (%rax),%xmm0
  mov    -0x90(%rbp),%rax
  movsd  (%rax),%xmm1
  subsd  %xmm1,%xmm0
  movsd  %xmm0,-0x50(%rbp)
  mov    -0xa0(%rbp),%rax
  add    $0x8,%rax
  movsd  (%rax),%xmm0
  mov    -0x90(%rbp),%rax
  add    $0x8,%rax
  movsd  (%rax),%xmm1
  subsd  %xmm1,%xmm0
  movsd  %xmm0,-0x48(%rbp)
  mov    -0xa0(%rbp),%rax
  add    $0x10,%rax
  movsd  (%rax),%xmm0
  mov    -0x90(%rbp),%rax
  add    $0x10,%rax
  movsd  (%rax),%xmm1
  subsd  %xmm1,%xmm0
  movsd  %xmm0,-0x40(%rbp)
  lea    -0x30(%rbp),%rdx
  lea    -0x50(%rbp),%rcx
  lea    -0x70(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <crossVectorsNorm_double@plt>
  lea    -0x30(%rbp),%rax
  mov    %rax,%rdi
  call   <magnitudeVector_double@plt>
  test   %rax,%rax
  jne    L14
  mov    -0x90(%rbp),%rax
  movsd  (%rax),%xmm0
  movsd  %xmm0,-0x30(%rbp)
  mov    -0x90(%rbp),%rax
  add    $0x8,%rax
  movsd  (%rax),%xmm0
  movsd  %xmm0,-0x28(%rbp)
  mov    -0x90(%rbp),%rax
  add    $0x10,%rax
  movsd  (%rax),%xmm0
  movsd  %xmm0,-0x20(%rbp)
  lea    -0x30(%rbp),%rax
  mov    %rax,%rdi
  call   <normalizeVector_double@plt>
L14:
  lea    -0x30(%rbp),%rdx
  mov    -0x90(%rbp),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <dotVectors_double@plt>
  movq   %xmm0,%rbx
  lea    -0x30(%rbp),%rdx
  mov    -0x88(%rbp),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <dotVectors_double@plt>
  movapd %xmm0,%xmm1
  movq   %rbx,%xmm0
  divsd  %xmm1,%xmm0
  movsd  %xmm0,-0x78(%rbp)
  mov    -0x88(%rbp),%rax
  movsd  (%rax),%xmm0
  mulsd  -0x78(%rbp),%xmm0
  mov    -0xa8(%rbp),%rax
  movsd  %xmm0,(%rax)
  mov    -0x88(%rbp),%rax
  add    $0x8,%rax
  movsd  (%rax),%xmm0
  mov    -0xa8(%rbp),%rax
  add    $0x8,%rax
  mulsd  -0x78(%rbp),%xmm0
  movsd  %xmm0,(%rax)
  mov    -0x88(%rbp),%rax
  add    $0x10,%rax
  movsd  (%rax),%xmm0
  mov    -0xa8(%rbp),%rax
  add    $0x10,%rax
  mulsd  -0x78(%rbp),%xmm0
  movsd  %xmm0,(%rax)
  nop
  mov    -0x18(%rbp),%rax
  sub    %fs:0x28,%rax
  je     L13
  call   <__stack_chk_fail@plt>
L13:
  mov    -0x8(%rbp),%rbx
  leave
  ret
```

assistant: ```c
void projectPoint_double(const double *point, const double *v0, const double *v1, const double *v2, double *projected_point) {
  double v0v1[3], v0v2[3], norm[3];
  double s;
  v0v1[0] = v1[0] - v0[0];
  v0v1[1] = v1[1] - v0[1];
  v0v1[2] = v1[2] - v0[2];
  v0v2[0] = v2[0] - v0[0];
  v0v2[1] = v2[1] - v0[1];
  v0v2[2] = v2[2] - v0[2];
  crossVectorsNorm_double(v0v1, v0v2, norm);
  if (magnitudeVector_double(norm) == 0) {
    norm[0] = v0[0];
    norm[1] = v0[1];
    norm[2] = v0[2];
    normalizeVector_double(norm);
  }
  s = dotVectors_double(v0, norm) / dotVectors_double(point, norm);
  projected_point[0] = s * point[0];
  projected_point[1] = s * point[1];
  projected_point[2] = s * point[2];
  return;
}
```