mirror of
https://github.com/Pomax/BezierInfo-2.git
synced 2025-09-01 12:23:19 +02:00
en sections 31-35
This commit is contained in:
16
components/sections/projections/content.en-GB.md
Normal file
16
components/sections/projections/content.en-GB.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# Projecting a point onto a Bézier curve
|
||||
|
||||
Say we have a Bézier curve and some point, not on the curve, of which we want to know which `t` value on the curve gives us an on-curve point closest to our off-curve point. Or: say we want to find the projection of a random point onto a curve. How do we do that?
|
||||
|
||||
If the Bézier curve is of low enough order, we might be able to [work out the maths for how to do this](http://jazzros.blogspot.ca/2011/03/projecting-point-on-bezier-curve.html), and get a perfect `t` value back, but in general this is an incredibly hard problem and the easiest solution is, really, a numerical approach again. We'll be finding our ideal `t` value using a [binary search](https://en.wikipedia.org/wiki/Binary_search_algorithm). First, we do a coarse distance-check based on `t` values associated with the curve's "to draw" coordinates (using a lookup table, or LUT). This is pretty fast. Then we run this algorithm:
|
||||
|
||||
1. with the `t` value we found, start with some small interval around `t` (1/length_of_LUT on either side is a reasonable start),
|
||||
2. if the distance to `t ± interval/2` is larger than the distance to `t`, try again with the interval reduced to half its original length.
|
||||
3. if the distance to `t ± interval/2` is smaller than the distance to `t`, replace `t` with the smaller-distance value.
|
||||
4. after reducing the interval, or changing `t`, go back to step 1.
|
||||
|
||||
We keep repeating this process until the interval is small enough to claim the difference in precision found is irrelevant for the purpose we're trying to find `t` for. In this case, I'm arbitrarily fixing it at 0.0001.
|
||||
|
||||
The following graphic demonstrates the result of this procedure.Simply move the cursor around, and if it does not lie on top of the curve, you will see a line that projects the cursor onto the curve based on an iteratively found "ideal" `t` value.
|
||||
|
||||
<Graphic preset="simple" title="Projecting a point onto a Bézier curve" setup={this.setup} draw={this.draw} onMouseMove={this.onMouseMove}/>
|
@@ -1,11 +1,13 @@
|
||||
var React = require("react");
|
||||
var Graphic = require("../../Graphic.jsx");
|
||||
var SectionHeader = require("../../SectionHeader.jsx");
|
||||
|
||||
var Locale = require("../../../lib/locale");
|
||||
var locale = new Locale();
|
||||
var page = "projections";
|
||||
|
||||
var Projections = React.createClass({
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
title: "Projecting a point onto a Bézier curve"
|
||||
title: locale.getTitle(page)
|
||||
};
|
||||
},
|
||||
|
||||
@@ -64,41 +66,7 @@ var Projections = React.createClass({
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<section>
|
||||
<SectionHeader {...this.props} />
|
||||
|
||||
<p>Say we have a Bézier curve and some point, not on the curve, of which we want to know
|
||||
which <i>t</i> value on the curve gives us an on-curve point closest to our off-curve point.
|
||||
Or: say we want to find the projection of a random point onto a curve. How do we do that?</p>
|
||||
|
||||
<p>If the Bézier curve is of low enough order, we might be able
|
||||
to <a href="http://jazzros.blogspot.ca/2011/03/projecting-point-on-bezier-curve.html">work out
|
||||
the maths for how to do this</a>, and get a perfect <i>t</i> value back, but in general this is
|
||||
an incredibly hard problem and the easiest solution is, really, a numerical approach again. We'll
|
||||
be finding our ideal <i>t</i> value using a <a href="https://en.wikipedia.org/wiki/Binary_search_algorithm">binary
|
||||
search</a>. First, we do a coarse distance-check based on <i>t</i> values associated with the
|
||||
curve's "to draw" coordinates (using a lookup table, or LUT). This is pretty fast. Then we run
|
||||
this algorithm:</p>
|
||||
|
||||
<ol>
|
||||
<li>with the <i>t</i> value we found, start with some small interval around <i>t</i> (1/length_of_LUT on either side is a reasonable start),</li>
|
||||
<li>if the distance to <i>t ± interval/2</i> is larger than the distance to <i>t</i>, try again with the interval reduced to half its original length.</li>
|
||||
<li>if the distance to <i>t ± interval/2</i> is smaller than the distance to <i>t</i>, replace <i>t</i> with the smaller-distance value.</li>
|
||||
<li>after reducing the interval, or changing <i>t</i>, go back to step 1.</li>
|
||||
</ol>
|
||||
|
||||
<p>We keep repeating this process until the interval is small enough to claim the difference
|
||||
in precision found is irrelevant for the purpose we're trying to find <i>t</i> for. In this
|
||||
case, I'm arbitrarily fixing it at 0.0001.</p>
|
||||
|
||||
<p>The following graphic demonstrates the result of this procedure.Simply move the cursor
|
||||
around, and if it does not lie on top of the curve, you will see a line that projects the
|
||||
cursor onto the curve based on an iteratively found "ideal" <i>t</i> value.</p>
|
||||
|
||||
<Graphic preset="simple" title="Projecting a point onto a Bézier curve" setup={this.setup} draw={this.draw} onMouseMove={this.onMouseMove}/>
|
||||
</section>
|
||||
);
|
||||
return locale.getContent(page, this);
|
||||
}
|
||||
});
|
||||
|
||||
|
Reference in New Issue
Block a user