Skip to content

Instantly share code, notes, and snippets.

@beyondlimits
Last active January 26, 2021 21:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save beyondlimits/57379715d56d9e6f6856d373b8aa68ed to your computer and use it in GitHub Desktop.
Save beyondlimits/57379715d56d9e6f6856d373b8aa68ed to your computer and use it in GitHub Desktop.
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="style.css" type="text/css"/>
<meta charset="utf-8"/>
<title>NURBS</title>
</head>
<body>
<canvas id="canvas" width="400" height="400">
</canvas>
<script src="TheWild.js" type="text/javascript"></script>
<script src="script.js" type="text/javascript"></script>
</body>
</html>
'use strict';
!function(){
var a = Math.sqrt(2) / 2;
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
TheWild.canvas = canvas;
TheWild.context = context;
function drawPoint(x, y) {
context.fillStyle = 'red';
context.beginPath();
context.arc(x, y, 5, 0, 2 * Math.PI);
context.fill();
}
/*
for (var i = 0; i < 8; ++i) {
drawPoint(TheWild.x[i], TheWild.y[i]);
}
*/
context.strokeStyle = '#F006';
context.lineWidth = 2;
context.beginPath();
for (var i = 0; i <= 100; ++i) {
var t = i / 10;
var x = TheWild.multiplyArrays(TheWild.x, TheWild.w);
var y = TheWild.multiplyArrays(TheWild.y, TheWild.w);
x = TheWild.evaluate(t, TheWild.degree, x, TheWild.knots);
y = TheWild.evaluate(t, TheWild.degree, y, TheWild.knots);
var w = TheWild.evaluate(t, TheWild.degree, TheWild.w, TheWild.knots);
x /= w;
y /= w;
i ? context.lineTo(x, y) : context.moveTo(x, y);
}
context.stroke();
/*
var x = [ 1, 1, 0, -1, -1, -1, 0, 1, 1];
var y = [ 0, 1, 1, 1, 0, -1, -1, -1, 0];
var w = [ 1, a, 1, a, 1, a, 1, a, 1];
var knots = [0, 0, 1, 1, 2, 2, 3, 3, 4, 4];
var degree = 2;
var order = 3;
*/
/*
var x = [ 1, 1, 0];
var y = [ 0, 1, 1];
var w = [ 1, a, 1];
var knots = [0, 0, 1, 1];
var degree = 2;
var order = 3;
*/
/*
var xWeighted = TheWild.multiplyArrays(x, w);
var yWeighted = TheWild.multiplyArrays(y, w);
//evaluate(0.5, degree, x
var t = Math.random() + 4;
var px = TheWild.evaluate(t, degree, xWeighted, knots);
var py = TheWild.evaluate(t, degree, yWeighted, knots);
var pw = TheWild.evaluate(t, degree, w, knots);
px /= pw;
py /= pw;
console.log(px);
console.log(py);
console.log(px * px + py * py);
*/
}();
body {
margin: 0;
padding: 0;
}
#canvas {
background: url(reference2.png);
}
'use strict';
Object.defineProperty(this, 'TheWild', {value: function(){
var TheWild = {
x: [150, 50, 250, 250, 200, 350, 350, 200],
y: [300, 250, 250, 200, 150, 50, 300, 350],
w: [ 1, 1, 1, 1, 1, 1, 1, 1],
originalKnots: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
knots: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
//knots: [0, 0.9, 1.3, 1.9, 2.5, 6.1, 8.1, 8.9, 10],
degree: 3,
order: 4,
}
function lerp(t, a, b) {
if (a == b) {
return a;
}
t = +t;
if (t != t) {
throw new TypeError('t is not a number');
}
if (t < 0 || t > 1) {
throw new TypeError('t is out of range');
}
a = +a;
if (a != a) {
throw new TypeError('a is not a number');
}
b = +b;
if (b != b) {
throw new TypeError('b is not a number');
}
return a + (b - a) * t;
};
function ilerp(v, a, b) {
if (a == b) {
return a;
}
v = +v;
if (v != v) {
throw new TypeError('v is not a number');
}
if (v < a || v > b) {
throw new TypeError('v is out of range');
}
a = +a;
if (a != a) {
throw new TypeError('a is not a number');
}
b = +b;
if (b != b) {
throw new TypeError('b is not a number');
}
return (v - a) / (b - a);
}
function multiplyArrays(a, b) {
if (!(a instanceof Array)) {
throw new TypeError('a is not an array');
}
if (!(b instanceof Array)) {
throw new TypeError('b is not an array');
}
var c = [];
for (var i = 0, n = a.length; i < n; ++i) {
c.push(a[i] * b[i]);
}
return c;
}
function getIntervals(t, degree, knots) {
var result = [];
for (var a = 0, b = degree, n = knots.length; b < n; ++a, ++b) {
if (knots[a] <= t && t <= knots[b]) {
result.push({
segment: a,
position: ilerp(t, knots[a], knots[b]),
start: knots[a],
end: knots[b]
});
}
}
//console.log('intervals', result);
return result;
}
function collapse(t, arr) {
var result = [];
for (var a = 0, b = 1, n = arr.length; b < n; ++a, ++b) {
result.push({
value: lerp(ilerp(t, arr[b].start, arr[a].end), arr[a].value, arr[b].value),
start: arr[b].start,
end: arr[a].end
});
}
return result;
};
function evaluate(t, degree, values, knots) {
var arr = [];
var intervals = getIntervals(t, degree, knots);
var n = intervals.length;
if (n >= degree) {
for (var i = 0; i < n; ++i) {
var interval = intervals[i];
arr.push({
value: lerp(interval.position, values[interval.segment], values[interval.segment + 1]),
start: interval.start,
end: interval.end,
});
}
console.log(arr);
while (arr.length > 1) {
arr = collapse(t, arr);
}
return arr[0].value;
}
}
TheWild.lerp = lerp;
TheWild.ilerp = ilerp;
TheWild.multiplyArrays = multiplyArrays;
TheWild.getIntervals = getIntervals;
TheWild.collapse = collapse;
TheWild.evaluate = evaluate;
return TheWild;
}()});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment