B-spline: Difference between revisions
(julia example) |
(Added Wren) |
||
Line 36: | Line 36: | ||
plt = plot(map(a -> a.x, controlpoints), map(a -> a.y, controlpoints)) |
plt = plot(map(a -> a.x, controlpoints), map(a -> a.y, controlpoints)) |
||
savefig(plt, "BSplineplot.png") |
savefig(plt, "BSplineplot.png") |
||
=={{header|Wren}}== |
|||
{{libheader|DOME}} |
|||
In the absence of any clarification on what to use (see Talk page), the following uses a degree of 3 (i.e order k = 4) and a uniform knot vector from 1 to 16 (as there are 12 control points) with a delta of 1. |
|||
If one uses a value for k of 1, then the script will simply plot the control points as in the Julia example. |
|||
<lang ecmascript>import "dome" for Window, Process |
|||
import "graphics" for Canvas, Color |
|||
class BSpline { |
|||
construct new(width, height, cpoints, k) { |
|||
Window.resize(width, height) |
|||
Canvas.resize(width, height) |
|||
Window.title = "B-spline curve" |
|||
_p = cpoints |
|||
_n = cpoints.count - 1 |
|||
_k = k |
|||
_t = (1.._n + 1 + k).toList // use a uniform knot vector, delta = 1 |
|||
} |
|||
// B-spline helper function |
|||
w(i, k, x) { (_t[i+k] != _t[i]) ? (x - _t[i]) / (_t[i+k] - _t[i]) : 0 } |
|||
// B-spline function |
|||
b(i, k, x) { |
|||
if (k == 1) return (_t[i] <= x && x < _t[i + 1]) ? 1 : 0 |
|||
return w(i, k-1, x) * b(i, k-1, x) + (1 - w(i+1, k-1, x)) * b(i+1, k-1, x) |
|||
} |
|||
// B-spline points |
|||
p() { |
|||
var bpoints = [] |
|||
for (x in _t[_k-1]..._t[_n + 1]) { |
|||
var sumX = 0 |
|||
var sumY = 0 |
|||
for (i in 0.._n) { |
|||
var f = b(i, _k, x) |
|||
sumX = sumX + f * _p[i][0] |
|||
sumY = sumY + f * _p[i][1] |
|||
} |
|||
bpoints.add([sumX.round, sumY.round]) |
|||
} |
|||
return bpoints |
|||
} |
|||
init() { |
|||
if (_k > _n + 1 || _k < 1) { |
|||
System.print("k (= %(_k)) can't be more than %(_n+1) or less than 1.") |
|||
Process.exit() |
|||
} |
|||
var bpoints = p() |
|||
// plot the curve |
|||
for (i in 1...bpoints.count) { |
|||
Canvas.line(bpoints[i-1][0], bpoints[i-1][1], bpoints[i][0], bpoints[i][1], Color.white) |
|||
} |
|||
} |
|||
update() {} |
|||
draw(alpha) {} |
|||
} |
|||
var cpoints = [ |
|||
[171, 171], [185, 111], [202, 109], [202, 189], [328, 160], [208, 254], |
|||
[241, 330], [164, 252], [ 69, 278], [139, 208], [ 72, 148], [168, 172] |
|||
] |
|||
var k = 4 // polynomial degree is one less than this i.e. cubic |
|||
var Game = BSpline.new(400, 400, cpoints, k)</lang> |
Revision as of 16:07, 2 September 2021
- Task
Generate a B-spline curve with a list of 12 points and plot or save image.
Coordinates of control points:
start=171,171 1 185,111, 2 202,109, 3 202,189 4 328,160 5 208,254 6 241,330 7 164,252 8 69,278 9 139,208 10 72,148 end=168,172
Rules!!!!
Do not use third party libraries or functions
- See also
Julia
Choose BSpline D of 2, ie degree 1. <lang julia>using Graphics, Plots
Point(t::Tuple) = Vec2(Float64(t[1]), Float64(t[2])) const controlpoints = Point.([(171, 171), (185, 111), (202, 109), (202, 189), (328, 160),
(208, 254), (241, 330), (164,252), (69, 278), (139, 208), (72, 148), (168, 172)])
plt = plot(map(a -> a.x, controlpoints), map(a -> a.y, controlpoints)) savefig(plt, "BSplineplot.png")
Wren
In the absence of any clarification on what to use (see Talk page), the following uses a degree of 3 (i.e order k = 4) and a uniform knot vector from 1 to 16 (as there are 12 control points) with a delta of 1.
If one uses a value for k of 1, then the script will simply plot the control points as in the Julia example. <lang ecmascript>import "dome" for Window, Process import "graphics" for Canvas, Color
class BSpline {
construct new(width, height, cpoints, k) { Window.resize(width, height) Canvas.resize(width, height) Window.title = "B-spline curve" _p = cpoints _n = cpoints.count - 1 _k = k _t = (1.._n + 1 + k).toList // use a uniform knot vector, delta = 1 }
// B-spline helper function w(i, k, x) { (_t[i+k] != _t[i]) ? (x - _t[i]) / (_t[i+k] - _t[i]) : 0 } // B-spline function b(i, k, x) { if (k == 1) return (_t[i] <= x && x < _t[i + 1]) ? 1 : 0 return w(i, k-1, x) * b(i, k-1, x) + (1 - w(i+1, k-1, x)) * b(i+1, k-1, x) }
// B-spline points p() { var bpoints = [] for (x in _t[_k-1]..._t[_n + 1]) { var sumX = 0 var sumY = 0 for (i in 0.._n) { var f = b(i, _k, x) sumX = sumX + f * _p[i][0] sumY = sumY + f * _p[i][1] } bpoints.add([sumX.round, sumY.round]) } return bpoints }
init() { if (_k > _n + 1 || _k < 1) { System.print("k (= %(_k)) can't be more than %(_n+1) or less than 1.") Process.exit() } var bpoints = p() // plot the curve for (i in 1...bpoints.count) { Canvas.line(bpoints[i-1][0], bpoints[i-1][1], bpoints[i][0], bpoints[i][1], Color.white) } }
update() {}
draw(alpha) {}
}
var cpoints = [
[171, 171], [185, 111], [202, 109], [202, 189], [328, 160], [208, 254], [241, 330], [164, 252], [ 69, 278], [139, 208], [ 72, 148], [168, 172]
] var k = 4 // polynomial degree is one less than this i.e. cubic var Game = BSpline.new(400, 400, cpoints, k)</lang>