Closed quillaja closed 6 years ago
Hi. I decided to look into this a little more today, and I think I've found the error. The error is in choose()
and is due to integer division and the truncation that happens. Using a float internally to accumulate your result then casting to int at the end fixes the issue. Very easy fix. See below.
I haven't tested this with the actual bezier functions, but I noticed that CubicBezierCurve2D()
explicitly lists the coefficients which BezierCurve2D()
calculates via choose()
. These coefficients are 1, 3, 3, 1, as expected. I copied the choose()
function into the go playground and messed around with it. The current choose()
produces 1, 3, 2, 1. This is clearly not the binomial coefficient, and explains why in the above examples the 3rd control point appears "ignored".
This error will also affect the other arbitrary-length control point bezier functions (eg BezierCurve3D
). It would not be noticeable for a 3 point bezier curve where the coefficients are 1, 2, 1, but will be very noticeable as the number of control points increases.
Here is the simple fixed version.
func choose(n, k int) int {
if k == 0 {
return 1
} else if n == 0 {
return 0
}
result := float64(n - (k - 1))
for i := 2; i <= k; i++ {
result *= float64(n-(k-i)) / float64(i)
}
return int(result)
}
I ran the above test plots again with the code in PR #71. I had to increase the width of the line for BezierCurve2D
(the red one) so it was visible under the expected green one from CubicBezierCurve2D
.
I've been using the bezier curve functions in
mgl64
lately, and I might have found an error inBezierCurve2D()
. I noticed this when I plotted a cubic curve (4 control points) using theBezierCurve2D()
and it did not produce the expected curve. I plotted the same curve usingCubicBezierCurve2D()
and got the expected result. In this case, I used the control points{4, 5}, {5.2, 6.3556}, {6.2, 4.2444}, {6, 3}
.Here's an image showing the 2 curves. Red is from
BezierCurve2D()
and green is the expected curve fromCubicBezierCurve2D()
.The code which produced this is below. I used the gosl/plt package to create the plot.
Another example with the control points
{0, 0}, {1, 3}, {3, 3}, {6, 0}
: