mirror of
https://github.com/PolarisSS13/Polaris.git
synced 2026-07-10 15:52:39 +01:00
5a52ebcaa5
adds _version.dm compatibility file + core/math/math.dm dependency adds polyvis.html tool to go along with math.dm converts uses of n_ceil to ceil
169 lines
4.3 KiB
HTML
169 lines
4.3 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>cbrand picker</title>
|
|
<style>
|
|
html, body {
|
|
background-color: #222;
|
|
color: #eee;
|
|
}
|
|
</style>
|
|
<script type="module">
|
|
|
|
const quadratic_interp = (t, p0, p1, p2) => {
|
|
const mt = 1 - t
|
|
return p0 * mt * mt +
|
|
2 * p1 * mt * t +
|
|
p2 * t * t
|
|
}
|
|
|
|
const cubic_interp = (t, p0, p1, p2, p3) => {
|
|
const t2 = t * t
|
|
const mt = 1 - t
|
|
const mt2 = mt * mt
|
|
return p0 * mt2 * mt +
|
|
3 * p1 * mt2 * t +
|
|
3 * p2 * mt * t2 +
|
|
p3 * t2 * t
|
|
}
|
|
|
|
const quartic_interp = (t, p0, p1, p2, p3, p4) => {
|
|
const t2 = t * t
|
|
const t3 = t2 * t
|
|
const mt = 1 - t
|
|
const mt2 = mt * mt
|
|
const mt3 = mt2 * mt
|
|
return p0 * mt3 * mt +
|
|
4 * p1 * mt3 * t +
|
|
6 * p2 * mt2 * t2 +
|
|
4 * p3 * mt * t3 +
|
|
p4 * t3 * t
|
|
}
|
|
|
|
const random_iterations = 1e5
|
|
|
|
const ctx = document.querySelector('canvas').getContext('2d')
|
|
const out = document.querySelector('#out')
|
|
|
|
const inputs = [ ...document.querySelectorAll('input[type="range"]') ]
|
|
.reduce(function (inputs, input) {
|
|
inputs[input.id] = input
|
|
return inputs
|
|
}, {})
|
|
|
|
let interp_func = quadratic_interp
|
|
let procname = 'interp2'
|
|
|
|
const funcSelector = document.querySelector('select')
|
|
|
|
funcSelector.addEventListener('change', updateInterpFunc)
|
|
|
|
function updateInterpFunc () {
|
|
if (funcSelector.value === 'quadratic') {
|
|
inputs['p4y'].setAttribute('hidden', true)
|
|
inputs['p5y'].setAttribute('hidden', true)
|
|
interp_func = quadratic_interp
|
|
procname = 'poly_interp2'
|
|
}
|
|
else if (funcSelector.value === 'cubic') {
|
|
inputs['p4y'].removeAttribute('hidden')
|
|
inputs['p5y'].setAttribute('hidden', true)
|
|
interp_func = cubic_interp
|
|
procname = 'poly_interp3'
|
|
}
|
|
else {
|
|
inputs['p4y'].removeAttribute('hidden')
|
|
inputs['p5y'].removeAttribute('hidden')
|
|
interp_func = quartic_interp
|
|
procname = 'poly_interp4'
|
|
}
|
|
}
|
|
|
|
function getInput (...ids) {
|
|
return ids.map(id => Number.parseFloat(inputs[id].value))
|
|
}
|
|
|
|
function getInputY () {
|
|
return getInput('p1y', 'p2y', 'p3y', 'p4y', 'p5y')
|
|
}
|
|
|
|
updateInterpFunc()
|
|
|
|
let lastInputs
|
|
|
|
requestAnimationFrame(function frame() {
|
|
requestAnimationFrame(frame)
|
|
let inputs = getInputY()
|
|
let sig = inputs.join() + funcSelector.value
|
|
if (sig === lastInputs)
|
|
return
|
|
lastInputs = sig
|
|
const { clientWidth: w, clientHeight: h } = ctx.canvas
|
|
ctx.strokeStyle = 'black'
|
|
ctx.fillStyle = 'black'
|
|
ctx.fillRect(0,0,w,h)
|
|
const [ y1, y2, y3, y4 ] = inputs
|
|
ctx.strokeStyle = 'dodgerblue'
|
|
ctx.lineWidth = 1.0
|
|
ctx.fillStyle = 'dodgerblue'
|
|
const results = new Array(101).fill(0)
|
|
for (let i = 1; i < random_iterations; ++i)
|
|
++results[Math.round(interp_func(Math.random(), ...inputs) * 100)]
|
|
let lowest = 100
|
|
let highest = 0
|
|
let mode = 0
|
|
let mode_val = 0
|
|
for (let i = 0; i <= 100; ++i) {
|
|
let val = results[i]
|
|
if (!val)
|
|
continue
|
|
if (val > mode_val) {
|
|
mode = i
|
|
mode_val = val
|
|
}
|
|
if (i < lowest)
|
|
lowest = i
|
|
if (i > highest)
|
|
highest = i
|
|
}
|
|
for (let i = lowest; i <= highest; ++i) {
|
|
let val = results[i]
|
|
ctx.fillRect(w, h - i * 0.01 * h, -((val / mode_val) * (w / 2)), h * 0.01)
|
|
}
|
|
ctx.strokeStyle = 'darkred'
|
|
ctx.lineWidth = 4.0
|
|
ctx.beginPath()
|
|
ctx.moveTo(0, h - inputs[0] * h)
|
|
for (let i = 1; i <= 100; ++i)
|
|
ctx.lineTo(i / 100 * w, h - interp_func(i / 100, ...inputs) * h)
|
|
ctx.stroke()
|
|
ctx.strokeStyle = 'white'
|
|
ctx.lineWidth = 1.0
|
|
ctx.strokeText(`${(highest/100).toFixed(2)}`, w/2 - 40, h - (highest * 0.01 * h) + 12)
|
|
ctx.strokeText(`${(lowest/100).toFixed(2)}`, w/2 - 40, h - (lowest * 0.01 * h) - 12)
|
|
ctx.strokeStyle = 'green'
|
|
ctx.strokeRect(0, 0, w, h)
|
|
out.innerText = `${procname}(${inputs.join(', ')}, rand())`
|
|
})
|
|
</script>
|
|
</head>
|
|
<body>
|
|
<select>
|
|
<option value="quadratic">quadratic</option>
|
|
<option value="cubic">cubic</option>
|
|
<option value="quartic">quartic</option>
|
|
</select>
|
|
<p><input id="p1y" type="range" min="0" max="1" step="0.01" value="0"></p>
|
|
<p><input id="p2y" type="range" min="0" max="1" step="0.01" value="0.8"></p>
|
|
<p><input id="p3y" type="range" min="0" max="1" step="0.01" value="0.2"></p>
|
|
<p><input id="p4y" type="range" min="0" max="1" step="0.01" value="1"></p>
|
|
<p><input id="p5y" type="range" min="0" max="1" step="0.01" value="1"></p>
|
|
<p>red line: the sample curve.</p>
|
|
<p>blue bars: the distribution, given random 0..1 numbers.</p>
|
|
<p>white numbers: rough min/max values possible.</p>
|
|
<p>dm call: <span id="out"></span></p>
|
|
<p><canvas id="shape" width="500" height="500"></canvas></p>
|
|
</body>
|
|
</html>
|