Tangent line to a 3D curve at a given 3D point












-1












$begingroup$


I'm trying to compute tangent vector(x,y,z) to a 3D curve(start x1,y1,z1 end x2,y2,z2) at a point (x0,y0,z0). Can anyone tell if this information is sufficient to calculate the tangent vector? If yes can anyone tell the formula with the help of some values. Help is greatly appreciated!!!










share|cite|improve this question









$endgroup$












  • $begingroup$
    You need some equation or description of the curve. There are a lot of them that go through three points in space.
    $endgroup$
    – amd
    Jan 10 at 20:47
















-1












$begingroup$


I'm trying to compute tangent vector(x,y,z) to a 3D curve(start x1,y1,z1 end x2,y2,z2) at a point (x0,y0,z0). Can anyone tell if this information is sufficient to calculate the tangent vector? If yes can anyone tell the formula with the help of some values. Help is greatly appreciated!!!










share|cite|improve this question









$endgroup$












  • $begingroup$
    You need some equation or description of the curve. There are a lot of them that go through three points in space.
    $endgroup$
    – amd
    Jan 10 at 20:47














-1












-1








-1





$begingroup$


I'm trying to compute tangent vector(x,y,z) to a 3D curve(start x1,y1,z1 end x2,y2,z2) at a point (x0,y0,z0). Can anyone tell if this information is sufficient to calculate the tangent vector? If yes can anyone tell the formula with the help of some values. Help is greatly appreciated!!!










share|cite|improve this question









$endgroup$




I'm trying to compute tangent vector(x,y,z) to a 3D curve(start x1,y1,z1 end x2,y2,z2) at a point (x0,y0,z0). Can anyone tell if this information is sufficient to calculate the tangent vector? If yes can anyone tell the formula with the help of some values. Help is greatly appreciated!!!







3d curves math-software






share|cite|improve this question













share|cite|improve this question











share|cite|improve this question




share|cite|improve this question










asked Jan 10 at 14:44









KushKush

1




1












  • $begingroup$
    You need some equation or description of the curve. There are a lot of them that go through three points in space.
    $endgroup$
    – amd
    Jan 10 at 20:47


















  • $begingroup$
    You need some equation or description of the curve. There are a lot of them that go through three points in space.
    $endgroup$
    – amd
    Jan 10 at 20:47
















$begingroup$
You need some equation or description of the curve. There are a lot of them that go through three points in space.
$endgroup$
– amd
Jan 10 at 20:47




$begingroup$
You need some equation or description of the curve. There are a lot of them that go through three points in space.
$endgroup$
– amd
Jan 10 at 20:47










1 Answer
1






active

oldest

votes


















0












$begingroup$


Can anyone tell if this information is sufficient to calculate the tangent vector?




No. We need to know the shape of the curve.





Knowing the curve passes via $vec{p}_s = (x_s , y_s , z_s)$ and $vec{p}_e = (x_e , y_e , z_e)$ does not tell us anything about the shape of the curve. In the simplest case, the curve would be a straight line, and in that case its tangent is everywhere the same, $vec{p}_e - vec{p}_s$.





In computer programs, cubic Bézier curves are ubiquitous. They are defined using four points. The curve passes through the first point $vec{p}_1 = (x_1 , y_1 , z_1) = vec{p}_s$ and the last point $vec{p}_4 = (x_4 , y_4 , z_4) = vec{p}_e$, but the other two just control the shape of the curve. Mathematically,
$$bbox{ begin{cases}
x(t) = (1-t)^3 x_1 + 3 (1-t)^2 t x_2 + 3 (1-t) t^2 x_3 + t^3 x_4 \
y(t) = (1-t)^3 y_1 + 3 (1-t)^2 t y_2 + 3 (1-t) t^2 y_3 + t^3 y_4 \
z(t) = (1-t)^3 z_1 + 3 (1-t)^2 t z_2 + 3 (1-t) t^2 z_3 + t^3 z_4 \
end{cases}, quad 0 le t le 1 } tag{1}label{NA1}$$

Note that that notation is just a good, easy form to express the curve. We could write the curve coordinates as third-degree polynomials,
$$bbox{ begin{cases}
x(t) = X_0 + t X_1 + t^2 X_2 + t^3 X_3 \
y(t) = Y_0 + t Y_1 + t^2 Y_2 + t^3 Y_3 \
z(t) = Z_0 + t Z_1 + t^2 Z_2 + t^3 Z_3 \
end{cases} }, quad bbox{begin{cases}
X_0 = x_1 \
X_1 = 3 x_2 - 3 x_1 \
X_2 = 3 x_3 - 6 x_2 + 3 x_1 \
X_3 = x_4 - 3 x_3 + 3 x_2 - x_1 \
end{cases} } tag{2}label{NA2}$$

but in computer programs $eqref{NA1}$ is more numerically stable.



Non-uniform rational B-splines are a more general form of curves, used especially in modeling. You can obtain the tangent vectors on NURBS using basically the same way as below; you just use the NURBS equations for the coordinates instead.



If you've ever used Inkscape to doodle shapes, you probably have used the Bézier curve tool to draw cubic Bézier curves already. Start and end points are shown as boxy dots, and those control points as "handles", a circular dot connected to the start or end point on the curve. They are used in PostScript and SVG formats as well.





The tangent vector at any point $t$ along the curve is simply the derivative of the coordinates. Using $eqref{NA2}$ above,
$$bbox{ begin{cases}
displaystyle frac{d x(t)}{d t} = X_1 + 2 X_2 t + 3 t^2 X_3 \
displaystyle frac{d y(t)}{d t} = Y_1 + 2 Y_2 t + 3 t^2 Y_3 \
displaystyle frac{d z(t)}{d t} = Z_1 + 2 Z_2 t + 3 t^2 Z_3 \
end{cases} } tag{3}label{NA3}$$



However, we can also describe the tangent in quadratic Bézier form, by deriving $eqref{NA1}$, and reordering the terms. We get
$$bbox{ begin{cases}
displaystyle frac{d x(t)}{d t} = (1-t)^2 ( 3 x_2 - 3 x_1) + 2 (1-t) t ( 3 x_3 - 3 x_2 ) + t^2 ( 3 x_4 - 3 x_3 ) \
displaystyle frac{d y(t)}{d t} = (1-t)^2 ( 3 y_2 - 3 y_1) + 2 (1-t) t ( 3 y_3 - 3 y_2 ) + t^2 ( 3 y_4 - 3 y_3 ) \
displaystyle frac{d z(t)}{d t} = (1-t)^2 ( 3 z_2 - 3 z_1) + 2 (1-t) t ( 3 z_3 - 3 z_2 ) + t^2 ( 3 z_4 - 3 z_3 ) \
end{cases} } tag{4}label{NA4}$$

This form, $eqref{NA4}$, is again numerically quite stable, and is very suitable for use in a computer program.





That leaves one more problem to solve: how to find the curve parameter $t$ that corresponds to a point I already have?



There are algebraic solutions for linear curves (lines), quadratic curves, and cubic curves. Essentially, you can pick one of the coordinate functions, say $x$, and solve
$$x(t) - x = 0$$
using any root-finding algorithm. For quadratic curves, you find up to two real $t$; for cubic, up to three real $t$. You ignore non-real roots and $t lt 0$ and $t gt 0$, and check the candidates left if $y(t) = y$ and $z(t) = z$ at sufficient precision.



In computer programs, you always do such tests as $lvert y(t) - y rvert le epsilon$ and $lvert z(t) - z rvert le epsilon$, where $epsilon$ represents the precision in your coordinates: the largest difference in coordinates that you consider neglible. For example, if you read your point cloud coordinates with three decimals, use $epsilon = 0.0005$.



If your computer program already implements a fast curve point evaluation function (the simple form is fast enough!), a binary search in $t$ may prove faster. (It is also a very interesting approach if you have many curve types, or use polynomial functions of possibly very high degree for your curves.) The only "trick" needed is that because some curves have loops (i.e., the coordinates are not monotonic functions), you may have to split the initial $0 le t le 1$ to smaller ranges, to ensure you find the $t$ on the curve closest to the specified point, rather than a value of $t$ that is closer than its nearby points. (It is the difference between local and global minima.)



Essentially, you pick one of the coordinate functions, a range $0 le t_{min} lt t_{max} le 1$ in which the function is monotonic (increases or decreases, but not both), and then



Function BSearch(coordfunc, target, tmin, tmax, epsilon):
Let vmin = coordfunc(tmin) - target
Let vmax = coordfunc(tmax) - target
If vmin > vmax:
Let ttmp = tmin ; tmin = tmax ; tmax = ttmp
Let vtmp = vmin ; vmin = vmax ; vmax = vtmp
End If
If vmin > 0:
Return tmin
Else If vmax < 0:
Return tmax
End If

Loop:
Let t = (tmin + tmax) / 2
If vmax - vmin <= epsilon:
Return t
End If

Let v = coordfunc(t) - target
If (v < 0) and (v >= vmin):
tmin = t
Else
If (v > 0) and (v <= vmax):
tmax = t
Else
If (v == 0):
Return t
Else:
# Function is non-monotonic.
Return Failed
End If
End Loop
End Loop


The function will return the value of t that is closest to the target coordinate, within the range specified. If it detects the function is non-monotonic, it will return Failed. Because the function is only sampled, it does not reliably detect non-monotonic functions, and can return a non-optimal t for such functions.






share|cite|improve this answer









$endgroup$













    Your Answer





    StackExchange.ifUsing("editor", function () {
    return StackExchange.using("mathjaxEditing", function () {
    StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
    StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["$", "$"], ["\\(","\\)"]]);
    });
    });
    }, "mathjax-editing");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "69"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    noCode: true, onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmath.stackexchange.com%2fquestions%2f3068714%2ftangent-line-to-a-3d-curve-at-a-given-3d-point%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0












    $begingroup$


    Can anyone tell if this information is sufficient to calculate the tangent vector?




    No. We need to know the shape of the curve.





    Knowing the curve passes via $vec{p}_s = (x_s , y_s , z_s)$ and $vec{p}_e = (x_e , y_e , z_e)$ does not tell us anything about the shape of the curve. In the simplest case, the curve would be a straight line, and in that case its tangent is everywhere the same, $vec{p}_e - vec{p}_s$.





    In computer programs, cubic Bézier curves are ubiquitous. They are defined using four points. The curve passes through the first point $vec{p}_1 = (x_1 , y_1 , z_1) = vec{p}_s$ and the last point $vec{p}_4 = (x_4 , y_4 , z_4) = vec{p}_e$, but the other two just control the shape of the curve. Mathematically,
    $$bbox{ begin{cases}
    x(t) = (1-t)^3 x_1 + 3 (1-t)^2 t x_2 + 3 (1-t) t^2 x_3 + t^3 x_4 \
    y(t) = (1-t)^3 y_1 + 3 (1-t)^2 t y_2 + 3 (1-t) t^2 y_3 + t^3 y_4 \
    z(t) = (1-t)^3 z_1 + 3 (1-t)^2 t z_2 + 3 (1-t) t^2 z_3 + t^3 z_4 \
    end{cases}, quad 0 le t le 1 } tag{1}label{NA1}$$

    Note that that notation is just a good, easy form to express the curve. We could write the curve coordinates as third-degree polynomials,
    $$bbox{ begin{cases}
    x(t) = X_0 + t X_1 + t^2 X_2 + t^3 X_3 \
    y(t) = Y_0 + t Y_1 + t^2 Y_2 + t^3 Y_3 \
    z(t) = Z_0 + t Z_1 + t^2 Z_2 + t^3 Z_3 \
    end{cases} }, quad bbox{begin{cases}
    X_0 = x_1 \
    X_1 = 3 x_2 - 3 x_1 \
    X_2 = 3 x_3 - 6 x_2 + 3 x_1 \
    X_3 = x_4 - 3 x_3 + 3 x_2 - x_1 \
    end{cases} } tag{2}label{NA2}$$

    but in computer programs $eqref{NA1}$ is more numerically stable.



    Non-uniform rational B-splines are a more general form of curves, used especially in modeling. You can obtain the tangent vectors on NURBS using basically the same way as below; you just use the NURBS equations for the coordinates instead.



    If you've ever used Inkscape to doodle shapes, you probably have used the Bézier curve tool to draw cubic Bézier curves already. Start and end points are shown as boxy dots, and those control points as "handles", a circular dot connected to the start or end point on the curve. They are used in PostScript and SVG formats as well.





    The tangent vector at any point $t$ along the curve is simply the derivative of the coordinates. Using $eqref{NA2}$ above,
    $$bbox{ begin{cases}
    displaystyle frac{d x(t)}{d t} = X_1 + 2 X_2 t + 3 t^2 X_3 \
    displaystyle frac{d y(t)}{d t} = Y_1 + 2 Y_2 t + 3 t^2 Y_3 \
    displaystyle frac{d z(t)}{d t} = Z_1 + 2 Z_2 t + 3 t^2 Z_3 \
    end{cases} } tag{3}label{NA3}$$



    However, we can also describe the tangent in quadratic Bézier form, by deriving $eqref{NA1}$, and reordering the terms. We get
    $$bbox{ begin{cases}
    displaystyle frac{d x(t)}{d t} = (1-t)^2 ( 3 x_2 - 3 x_1) + 2 (1-t) t ( 3 x_3 - 3 x_2 ) + t^2 ( 3 x_4 - 3 x_3 ) \
    displaystyle frac{d y(t)}{d t} = (1-t)^2 ( 3 y_2 - 3 y_1) + 2 (1-t) t ( 3 y_3 - 3 y_2 ) + t^2 ( 3 y_4 - 3 y_3 ) \
    displaystyle frac{d z(t)}{d t} = (1-t)^2 ( 3 z_2 - 3 z_1) + 2 (1-t) t ( 3 z_3 - 3 z_2 ) + t^2 ( 3 z_4 - 3 z_3 ) \
    end{cases} } tag{4}label{NA4}$$

    This form, $eqref{NA4}$, is again numerically quite stable, and is very suitable for use in a computer program.





    That leaves one more problem to solve: how to find the curve parameter $t$ that corresponds to a point I already have?



    There are algebraic solutions for linear curves (lines), quadratic curves, and cubic curves. Essentially, you can pick one of the coordinate functions, say $x$, and solve
    $$x(t) - x = 0$$
    using any root-finding algorithm. For quadratic curves, you find up to two real $t$; for cubic, up to three real $t$. You ignore non-real roots and $t lt 0$ and $t gt 0$, and check the candidates left if $y(t) = y$ and $z(t) = z$ at sufficient precision.



    In computer programs, you always do such tests as $lvert y(t) - y rvert le epsilon$ and $lvert z(t) - z rvert le epsilon$, where $epsilon$ represents the precision in your coordinates: the largest difference in coordinates that you consider neglible. For example, if you read your point cloud coordinates with three decimals, use $epsilon = 0.0005$.



    If your computer program already implements a fast curve point evaluation function (the simple form is fast enough!), a binary search in $t$ may prove faster. (It is also a very interesting approach if you have many curve types, or use polynomial functions of possibly very high degree for your curves.) The only "trick" needed is that because some curves have loops (i.e., the coordinates are not monotonic functions), you may have to split the initial $0 le t le 1$ to smaller ranges, to ensure you find the $t$ on the curve closest to the specified point, rather than a value of $t$ that is closer than its nearby points. (It is the difference between local and global minima.)



    Essentially, you pick one of the coordinate functions, a range $0 le t_{min} lt t_{max} le 1$ in which the function is monotonic (increases or decreases, but not both), and then



    Function BSearch(coordfunc, target, tmin, tmax, epsilon):
    Let vmin = coordfunc(tmin) - target
    Let vmax = coordfunc(tmax) - target
    If vmin > vmax:
    Let ttmp = tmin ; tmin = tmax ; tmax = ttmp
    Let vtmp = vmin ; vmin = vmax ; vmax = vtmp
    End If
    If vmin > 0:
    Return tmin
    Else If vmax < 0:
    Return tmax
    End If

    Loop:
    Let t = (tmin + tmax) / 2
    If vmax - vmin <= epsilon:
    Return t
    End If

    Let v = coordfunc(t) - target
    If (v < 0) and (v >= vmin):
    tmin = t
    Else
    If (v > 0) and (v <= vmax):
    tmax = t
    Else
    If (v == 0):
    Return t
    Else:
    # Function is non-monotonic.
    Return Failed
    End If
    End Loop
    End Loop


    The function will return the value of t that is closest to the target coordinate, within the range specified. If it detects the function is non-monotonic, it will return Failed. Because the function is only sampled, it does not reliably detect non-monotonic functions, and can return a non-optimal t for such functions.






    share|cite|improve this answer









    $endgroup$


















      0












      $begingroup$


      Can anyone tell if this information is sufficient to calculate the tangent vector?




      No. We need to know the shape of the curve.





      Knowing the curve passes via $vec{p}_s = (x_s , y_s , z_s)$ and $vec{p}_e = (x_e , y_e , z_e)$ does not tell us anything about the shape of the curve. In the simplest case, the curve would be a straight line, and in that case its tangent is everywhere the same, $vec{p}_e - vec{p}_s$.





      In computer programs, cubic Bézier curves are ubiquitous. They are defined using four points. The curve passes through the first point $vec{p}_1 = (x_1 , y_1 , z_1) = vec{p}_s$ and the last point $vec{p}_4 = (x_4 , y_4 , z_4) = vec{p}_e$, but the other two just control the shape of the curve. Mathematically,
      $$bbox{ begin{cases}
      x(t) = (1-t)^3 x_1 + 3 (1-t)^2 t x_2 + 3 (1-t) t^2 x_3 + t^3 x_4 \
      y(t) = (1-t)^3 y_1 + 3 (1-t)^2 t y_2 + 3 (1-t) t^2 y_3 + t^3 y_4 \
      z(t) = (1-t)^3 z_1 + 3 (1-t)^2 t z_2 + 3 (1-t) t^2 z_3 + t^3 z_4 \
      end{cases}, quad 0 le t le 1 } tag{1}label{NA1}$$

      Note that that notation is just a good, easy form to express the curve. We could write the curve coordinates as third-degree polynomials,
      $$bbox{ begin{cases}
      x(t) = X_0 + t X_1 + t^2 X_2 + t^3 X_3 \
      y(t) = Y_0 + t Y_1 + t^2 Y_2 + t^3 Y_3 \
      z(t) = Z_0 + t Z_1 + t^2 Z_2 + t^3 Z_3 \
      end{cases} }, quad bbox{begin{cases}
      X_0 = x_1 \
      X_1 = 3 x_2 - 3 x_1 \
      X_2 = 3 x_3 - 6 x_2 + 3 x_1 \
      X_3 = x_4 - 3 x_3 + 3 x_2 - x_1 \
      end{cases} } tag{2}label{NA2}$$

      but in computer programs $eqref{NA1}$ is more numerically stable.



      Non-uniform rational B-splines are a more general form of curves, used especially in modeling. You can obtain the tangent vectors on NURBS using basically the same way as below; you just use the NURBS equations for the coordinates instead.



      If you've ever used Inkscape to doodle shapes, you probably have used the Bézier curve tool to draw cubic Bézier curves already. Start and end points are shown as boxy dots, and those control points as "handles", a circular dot connected to the start or end point on the curve. They are used in PostScript and SVG formats as well.





      The tangent vector at any point $t$ along the curve is simply the derivative of the coordinates. Using $eqref{NA2}$ above,
      $$bbox{ begin{cases}
      displaystyle frac{d x(t)}{d t} = X_1 + 2 X_2 t + 3 t^2 X_3 \
      displaystyle frac{d y(t)}{d t} = Y_1 + 2 Y_2 t + 3 t^2 Y_3 \
      displaystyle frac{d z(t)}{d t} = Z_1 + 2 Z_2 t + 3 t^2 Z_3 \
      end{cases} } tag{3}label{NA3}$$



      However, we can also describe the tangent in quadratic Bézier form, by deriving $eqref{NA1}$, and reordering the terms. We get
      $$bbox{ begin{cases}
      displaystyle frac{d x(t)}{d t} = (1-t)^2 ( 3 x_2 - 3 x_1) + 2 (1-t) t ( 3 x_3 - 3 x_2 ) + t^2 ( 3 x_4 - 3 x_3 ) \
      displaystyle frac{d y(t)}{d t} = (1-t)^2 ( 3 y_2 - 3 y_1) + 2 (1-t) t ( 3 y_3 - 3 y_2 ) + t^2 ( 3 y_4 - 3 y_3 ) \
      displaystyle frac{d z(t)}{d t} = (1-t)^2 ( 3 z_2 - 3 z_1) + 2 (1-t) t ( 3 z_3 - 3 z_2 ) + t^2 ( 3 z_4 - 3 z_3 ) \
      end{cases} } tag{4}label{NA4}$$

      This form, $eqref{NA4}$, is again numerically quite stable, and is very suitable for use in a computer program.





      That leaves one more problem to solve: how to find the curve parameter $t$ that corresponds to a point I already have?



      There are algebraic solutions for linear curves (lines), quadratic curves, and cubic curves. Essentially, you can pick one of the coordinate functions, say $x$, and solve
      $$x(t) - x = 0$$
      using any root-finding algorithm. For quadratic curves, you find up to two real $t$; for cubic, up to three real $t$. You ignore non-real roots and $t lt 0$ and $t gt 0$, and check the candidates left if $y(t) = y$ and $z(t) = z$ at sufficient precision.



      In computer programs, you always do such tests as $lvert y(t) - y rvert le epsilon$ and $lvert z(t) - z rvert le epsilon$, where $epsilon$ represents the precision in your coordinates: the largest difference in coordinates that you consider neglible. For example, if you read your point cloud coordinates with three decimals, use $epsilon = 0.0005$.



      If your computer program already implements a fast curve point evaluation function (the simple form is fast enough!), a binary search in $t$ may prove faster. (It is also a very interesting approach if you have many curve types, or use polynomial functions of possibly very high degree for your curves.) The only "trick" needed is that because some curves have loops (i.e., the coordinates are not monotonic functions), you may have to split the initial $0 le t le 1$ to smaller ranges, to ensure you find the $t$ on the curve closest to the specified point, rather than a value of $t$ that is closer than its nearby points. (It is the difference between local and global minima.)



      Essentially, you pick one of the coordinate functions, a range $0 le t_{min} lt t_{max} le 1$ in which the function is monotonic (increases or decreases, but not both), and then



      Function BSearch(coordfunc, target, tmin, tmax, epsilon):
      Let vmin = coordfunc(tmin) - target
      Let vmax = coordfunc(tmax) - target
      If vmin > vmax:
      Let ttmp = tmin ; tmin = tmax ; tmax = ttmp
      Let vtmp = vmin ; vmin = vmax ; vmax = vtmp
      End If
      If vmin > 0:
      Return tmin
      Else If vmax < 0:
      Return tmax
      End If

      Loop:
      Let t = (tmin + tmax) / 2
      If vmax - vmin <= epsilon:
      Return t
      End If

      Let v = coordfunc(t) - target
      If (v < 0) and (v >= vmin):
      tmin = t
      Else
      If (v > 0) and (v <= vmax):
      tmax = t
      Else
      If (v == 0):
      Return t
      Else:
      # Function is non-monotonic.
      Return Failed
      End If
      End Loop
      End Loop


      The function will return the value of t that is closest to the target coordinate, within the range specified. If it detects the function is non-monotonic, it will return Failed. Because the function is only sampled, it does not reliably detect non-monotonic functions, and can return a non-optimal t for such functions.






      share|cite|improve this answer









      $endgroup$
















        0












        0








        0





        $begingroup$


        Can anyone tell if this information is sufficient to calculate the tangent vector?




        No. We need to know the shape of the curve.





        Knowing the curve passes via $vec{p}_s = (x_s , y_s , z_s)$ and $vec{p}_e = (x_e , y_e , z_e)$ does not tell us anything about the shape of the curve. In the simplest case, the curve would be a straight line, and in that case its tangent is everywhere the same, $vec{p}_e - vec{p}_s$.





        In computer programs, cubic Bézier curves are ubiquitous. They are defined using four points. The curve passes through the first point $vec{p}_1 = (x_1 , y_1 , z_1) = vec{p}_s$ and the last point $vec{p}_4 = (x_4 , y_4 , z_4) = vec{p}_e$, but the other two just control the shape of the curve. Mathematically,
        $$bbox{ begin{cases}
        x(t) = (1-t)^3 x_1 + 3 (1-t)^2 t x_2 + 3 (1-t) t^2 x_3 + t^3 x_4 \
        y(t) = (1-t)^3 y_1 + 3 (1-t)^2 t y_2 + 3 (1-t) t^2 y_3 + t^3 y_4 \
        z(t) = (1-t)^3 z_1 + 3 (1-t)^2 t z_2 + 3 (1-t) t^2 z_3 + t^3 z_4 \
        end{cases}, quad 0 le t le 1 } tag{1}label{NA1}$$

        Note that that notation is just a good, easy form to express the curve. We could write the curve coordinates as third-degree polynomials,
        $$bbox{ begin{cases}
        x(t) = X_0 + t X_1 + t^2 X_2 + t^3 X_3 \
        y(t) = Y_0 + t Y_1 + t^2 Y_2 + t^3 Y_3 \
        z(t) = Z_0 + t Z_1 + t^2 Z_2 + t^3 Z_3 \
        end{cases} }, quad bbox{begin{cases}
        X_0 = x_1 \
        X_1 = 3 x_2 - 3 x_1 \
        X_2 = 3 x_3 - 6 x_2 + 3 x_1 \
        X_3 = x_4 - 3 x_3 + 3 x_2 - x_1 \
        end{cases} } tag{2}label{NA2}$$

        but in computer programs $eqref{NA1}$ is more numerically stable.



        Non-uniform rational B-splines are a more general form of curves, used especially in modeling. You can obtain the tangent vectors on NURBS using basically the same way as below; you just use the NURBS equations for the coordinates instead.



        If you've ever used Inkscape to doodle shapes, you probably have used the Bézier curve tool to draw cubic Bézier curves already. Start and end points are shown as boxy dots, and those control points as "handles", a circular dot connected to the start or end point on the curve. They are used in PostScript and SVG formats as well.





        The tangent vector at any point $t$ along the curve is simply the derivative of the coordinates. Using $eqref{NA2}$ above,
        $$bbox{ begin{cases}
        displaystyle frac{d x(t)}{d t} = X_1 + 2 X_2 t + 3 t^2 X_3 \
        displaystyle frac{d y(t)}{d t} = Y_1 + 2 Y_2 t + 3 t^2 Y_3 \
        displaystyle frac{d z(t)}{d t} = Z_1 + 2 Z_2 t + 3 t^2 Z_3 \
        end{cases} } tag{3}label{NA3}$$



        However, we can also describe the tangent in quadratic Bézier form, by deriving $eqref{NA1}$, and reordering the terms. We get
        $$bbox{ begin{cases}
        displaystyle frac{d x(t)}{d t} = (1-t)^2 ( 3 x_2 - 3 x_1) + 2 (1-t) t ( 3 x_3 - 3 x_2 ) + t^2 ( 3 x_4 - 3 x_3 ) \
        displaystyle frac{d y(t)}{d t} = (1-t)^2 ( 3 y_2 - 3 y_1) + 2 (1-t) t ( 3 y_3 - 3 y_2 ) + t^2 ( 3 y_4 - 3 y_3 ) \
        displaystyle frac{d z(t)}{d t} = (1-t)^2 ( 3 z_2 - 3 z_1) + 2 (1-t) t ( 3 z_3 - 3 z_2 ) + t^2 ( 3 z_4 - 3 z_3 ) \
        end{cases} } tag{4}label{NA4}$$

        This form, $eqref{NA4}$, is again numerically quite stable, and is very suitable for use in a computer program.





        That leaves one more problem to solve: how to find the curve parameter $t$ that corresponds to a point I already have?



        There are algebraic solutions for linear curves (lines), quadratic curves, and cubic curves. Essentially, you can pick one of the coordinate functions, say $x$, and solve
        $$x(t) - x = 0$$
        using any root-finding algorithm. For quadratic curves, you find up to two real $t$; for cubic, up to three real $t$. You ignore non-real roots and $t lt 0$ and $t gt 0$, and check the candidates left if $y(t) = y$ and $z(t) = z$ at sufficient precision.



        In computer programs, you always do such tests as $lvert y(t) - y rvert le epsilon$ and $lvert z(t) - z rvert le epsilon$, where $epsilon$ represents the precision in your coordinates: the largest difference in coordinates that you consider neglible. For example, if you read your point cloud coordinates with three decimals, use $epsilon = 0.0005$.



        If your computer program already implements a fast curve point evaluation function (the simple form is fast enough!), a binary search in $t$ may prove faster. (It is also a very interesting approach if you have many curve types, or use polynomial functions of possibly very high degree for your curves.) The only "trick" needed is that because some curves have loops (i.e., the coordinates are not monotonic functions), you may have to split the initial $0 le t le 1$ to smaller ranges, to ensure you find the $t$ on the curve closest to the specified point, rather than a value of $t$ that is closer than its nearby points. (It is the difference between local and global minima.)



        Essentially, you pick one of the coordinate functions, a range $0 le t_{min} lt t_{max} le 1$ in which the function is monotonic (increases or decreases, but not both), and then



        Function BSearch(coordfunc, target, tmin, tmax, epsilon):
        Let vmin = coordfunc(tmin) - target
        Let vmax = coordfunc(tmax) - target
        If vmin > vmax:
        Let ttmp = tmin ; tmin = tmax ; tmax = ttmp
        Let vtmp = vmin ; vmin = vmax ; vmax = vtmp
        End If
        If vmin > 0:
        Return tmin
        Else If vmax < 0:
        Return tmax
        End If

        Loop:
        Let t = (tmin + tmax) / 2
        If vmax - vmin <= epsilon:
        Return t
        End If

        Let v = coordfunc(t) - target
        If (v < 0) and (v >= vmin):
        tmin = t
        Else
        If (v > 0) and (v <= vmax):
        tmax = t
        Else
        If (v == 0):
        Return t
        Else:
        # Function is non-monotonic.
        Return Failed
        End If
        End Loop
        End Loop


        The function will return the value of t that is closest to the target coordinate, within the range specified. If it detects the function is non-monotonic, it will return Failed. Because the function is only sampled, it does not reliably detect non-monotonic functions, and can return a non-optimal t for such functions.






        share|cite|improve this answer









        $endgroup$




        Can anyone tell if this information is sufficient to calculate the tangent vector?




        No. We need to know the shape of the curve.





        Knowing the curve passes via $vec{p}_s = (x_s , y_s , z_s)$ and $vec{p}_e = (x_e , y_e , z_e)$ does not tell us anything about the shape of the curve. In the simplest case, the curve would be a straight line, and in that case its tangent is everywhere the same, $vec{p}_e - vec{p}_s$.





        In computer programs, cubic Bézier curves are ubiquitous. They are defined using four points. The curve passes through the first point $vec{p}_1 = (x_1 , y_1 , z_1) = vec{p}_s$ and the last point $vec{p}_4 = (x_4 , y_4 , z_4) = vec{p}_e$, but the other two just control the shape of the curve. Mathematically,
        $$bbox{ begin{cases}
        x(t) = (1-t)^3 x_1 + 3 (1-t)^2 t x_2 + 3 (1-t) t^2 x_3 + t^3 x_4 \
        y(t) = (1-t)^3 y_1 + 3 (1-t)^2 t y_2 + 3 (1-t) t^2 y_3 + t^3 y_4 \
        z(t) = (1-t)^3 z_1 + 3 (1-t)^2 t z_2 + 3 (1-t) t^2 z_3 + t^3 z_4 \
        end{cases}, quad 0 le t le 1 } tag{1}label{NA1}$$

        Note that that notation is just a good, easy form to express the curve. We could write the curve coordinates as third-degree polynomials,
        $$bbox{ begin{cases}
        x(t) = X_0 + t X_1 + t^2 X_2 + t^3 X_3 \
        y(t) = Y_0 + t Y_1 + t^2 Y_2 + t^3 Y_3 \
        z(t) = Z_0 + t Z_1 + t^2 Z_2 + t^3 Z_3 \
        end{cases} }, quad bbox{begin{cases}
        X_0 = x_1 \
        X_1 = 3 x_2 - 3 x_1 \
        X_2 = 3 x_3 - 6 x_2 + 3 x_1 \
        X_3 = x_4 - 3 x_3 + 3 x_2 - x_1 \
        end{cases} } tag{2}label{NA2}$$

        but in computer programs $eqref{NA1}$ is more numerically stable.



        Non-uniform rational B-splines are a more general form of curves, used especially in modeling. You can obtain the tangent vectors on NURBS using basically the same way as below; you just use the NURBS equations for the coordinates instead.



        If you've ever used Inkscape to doodle shapes, you probably have used the Bézier curve tool to draw cubic Bézier curves already. Start and end points are shown as boxy dots, and those control points as "handles", a circular dot connected to the start or end point on the curve. They are used in PostScript and SVG formats as well.





        The tangent vector at any point $t$ along the curve is simply the derivative of the coordinates. Using $eqref{NA2}$ above,
        $$bbox{ begin{cases}
        displaystyle frac{d x(t)}{d t} = X_1 + 2 X_2 t + 3 t^2 X_3 \
        displaystyle frac{d y(t)}{d t} = Y_1 + 2 Y_2 t + 3 t^2 Y_3 \
        displaystyle frac{d z(t)}{d t} = Z_1 + 2 Z_2 t + 3 t^2 Z_3 \
        end{cases} } tag{3}label{NA3}$$



        However, we can also describe the tangent in quadratic Bézier form, by deriving $eqref{NA1}$, and reordering the terms. We get
        $$bbox{ begin{cases}
        displaystyle frac{d x(t)}{d t} = (1-t)^2 ( 3 x_2 - 3 x_1) + 2 (1-t) t ( 3 x_3 - 3 x_2 ) + t^2 ( 3 x_4 - 3 x_3 ) \
        displaystyle frac{d y(t)}{d t} = (1-t)^2 ( 3 y_2 - 3 y_1) + 2 (1-t) t ( 3 y_3 - 3 y_2 ) + t^2 ( 3 y_4 - 3 y_3 ) \
        displaystyle frac{d z(t)}{d t} = (1-t)^2 ( 3 z_2 - 3 z_1) + 2 (1-t) t ( 3 z_3 - 3 z_2 ) + t^2 ( 3 z_4 - 3 z_3 ) \
        end{cases} } tag{4}label{NA4}$$

        This form, $eqref{NA4}$, is again numerically quite stable, and is very suitable for use in a computer program.





        That leaves one more problem to solve: how to find the curve parameter $t$ that corresponds to a point I already have?



        There are algebraic solutions for linear curves (lines), quadratic curves, and cubic curves. Essentially, you can pick one of the coordinate functions, say $x$, and solve
        $$x(t) - x = 0$$
        using any root-finding algorithm. For quadratic curves, you find up to two real $t$; for cubic, up to three real $t$. You ignore non-real roots and $t lt 0$ and $t gt 0$, and check the candidates left if $y(t) = y$ and $z(t) = z$ at sufficient precision.



        In computer programs, you always do such tests as $lvert y(t) - y rvert le epsilon$ and $lvert z(t) - z rvert le epsilon$, where $epsilon$ represents the precision in your coordinates: the largest difference in coordinates that you consider neglible. For example, if you read your point cloud coordinates with three decimals, use $epsilon = 0.0005$.



        If your computer program already implements a fast curve point evaluation function (the simple form is fast enough!), a binary search in $t$ may prove faster. (It is also a very interesting approach if you have many curve types, or use polynomial functions of possibly very high degree for your curves.) The only "trick" needed is that because some curves have loops (i.e., the coordinates are not monotonic functions), you may have to split the initial $0 le t le 1$ to smaller ranges, to ensure you find the $t$ on the curve closest to the specified point, rather than a value of $t$ that is closer than its nearby points. (It is the difference between local and global minima.)



        Essentially, you pick one of the coordinate functions, a range $0 le t_{min} lt t_{max} le 1$ in which the function is monotonic (increases or decreases, but not both), and then



        Function BSearch(coordfunc, target, tmin, tmax, epsilon):
        Let vmin = coordfunc(tmin) - target
        Let vmax = coordfunc(tmax) - target
        If vmin > vmax:
        Let ttmp = tmin ; tmin = tmax ; tmax = ttmp
        Let vtmp = vmin ; vmin = vmax ; vmax = vtmp
        End If
        If vmin > 0:
        Return tmin
        Else If vmax < 0:
        Return tmax
        End If

        Loop:
        Let t = (tmin + tmax) / 2
        If vmax - vmin <= epsilon:
        Return t
        End If

        Let v = coordfunc(t) - target
        If (v < 0) and (v >= vmin):
        tmin = t
        Else
        If (v > 0) and (v <= vmax):
        tmax = t
        Else
        If (v == 0):
        Return t
        Else:
        # Function is non-monotonic.
        Return Failed
        End If
        End Loop
        End Loop


        The function will return the value of t that is closest to the target coordinate, within the range specified. If it detects the function is non-monotonic, it will return Failed. Because the function is only sampled, it does not reliably detect non-monotonic functions, and can return a non-optimal t for such functions.







        share|cite|improve this answer












        share|cite|improve this answer



        share|cite|improve this answer










        answered Jan 11 at 1:36









        Nominal AnimalNominal Animal

        7,0332517




        7,0332517






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Mathematics Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            Use MathJax to format equations. MathJax reference.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmath.stackexchange.com%2fquestions%2f3068714%2ftangent-line-to-a-3d-curve-at-a-given-3d-point%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            MongoDB - Not Authorized To Execute Command

            How to fix TextFormField cause rebuild widget in Flutter

            Npm cannot find a required file even through it is in the searched directory