1
0
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:
Pomax
2017-03-15 14:04:54 -07:00
parent 394be9f9a6
commit cd9bf5c27a
38 changed files with 355 additions and 522 deletions

View 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}/>

View File

@@ -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);
}
});