Skip to content

Instantly share code, notes, and snippets.

@rowanc1
Created April 20, 2020 18:59
Show Gist options
  • Save rowanc1/d15e55f5f6763b505066f36a54d3c52e to your computer and use it in GitHub Desktop.
Save rowanc1/d15e55f5f6763b505066f36a54d3c52e to your computer and use it in GitHub Desktop.
<ink-var name="r" value="0.35"></ink-var>
<ink-var name="points" value="5"></ink-var>
<ink-var name="inset" value="2.5"></ink-var>
<ink-var name="theta" value="0" format=".1f"></ink-var>
<ink-var name="xC" :value="getCoord(0, theta, 'x', 0, draw)[1] || (-0.5 + r)"></ink-var>
<ink-var name="yC" :value="getCoord(0, theta, 'y', 0, draw)[1] || 0.5"></ink-var>
<ink-var name="uX" value="-0.5"></ink-var>
<ink-var name="uY" value="0.5"></ink-var>
<ink-var name="zeroX" :value="getCoord(0, theta, 'x', 0, draw)[0]"></ink-var>
<ink-var name="zeroY" :value="getCoord(0, theta, 'y', 0, draw)[0]"></ink-var>
<ink-var name="draw" value="false" type="Boolean"></ink-var>
<h3>Sin and Cos for a Square</h3>
<ink-button :click="render({theta: 0, inset:1, points:50, draw: false})" label="Circle"></ink-button>
<ink-button :click="render({theta: 0, inset:2.5, points:5, draw: false})" label="Star"></ink-button>
<ink-button :click="render({draw: true})" label="Draw"></ink-button>
<ink-visible :visible="draw"><aside class="callout">Drag the purple node to create a custom curve!</aside></ink-visible>
<p>
Theta: <ink-dynamic bind="theta" min="0" step="0.01" :max="1" periodic="true" :transform="value*360" after="º"></ink-dynamic>
<ink-visible :visible="!draw">
Inset: <ink-dynamic bind="inset" min="1" step="0.5" :max="10"></ink-dynamic>
Points: <ink-dynamic bind="points" min="2" step="1" :max="20"></ink-dynamic>
</ink-visible>
</p>
<script>
const nP = 23;
const getUserCoord = (i, r) => [Math.cos(i/(nP+1)*Math.PI*2) * r - 0.5, Math.sin(i/(nP + 1)*Math.PI*2) * r + 0.5];
const path = Array(nP).fill(0).map((v,i) => getUserCoord(i, 0.35));
function setPath(x, y) {
const t = getTheta(x, y);
const r = getRadius(0.35, x, y);
const i = Math.round(t * nP)
path[i] = getUserCoord(i, r);
return {
uX: Math.max(Math.min(x, -0.5 + 0.35), -0.5 - 0.35),
uY: Math.max(Math.min(y, +0.5 + 0.35), +0.5 - 0.35),
}
}
function render(args) {
setTimeout(() => document.getElementById('squareWave').requestUpdate(), 100);
return args;
}
function getTheta(x, y) {
const angle = Math.atan2(y - 0.5, x + 0.5) / (2 * Math.PI);
return angle < 0 ? 1 + angle : angle;
}
function getRadius(r, x, y) {
const yN = Math.max(Math.min(Math.abs(y - 0.5), r), 0.01);
const xN = Math.max(Math.min(Math.abs(x + 0.5), r), 0.01);
return Math.sqrt(xN * xN + yN * yN)
}
function findDomain(theta, coord) {
const dir = getCoord(0.1, theta, coord)[0] < 1 ? +1 : -1;
let t = 0;
const step = 0.005 * dir;
t += step;
let trys = 0;
while (getCoord(t, theta, coord)[0] > 1 && trys < 10){
t += step;
trys += 1;
}
return t;
}
function getCoord(t, theta, coord, zero = 0, draw=false) {
const chart = document.getElementById('squareWave');
const path = draw ? chart.shadowRoot.querySelectorAll('path[stroke="purple"]')[0] : chart.shadowRoot.querySelectorAll('path[stroke="green"]')[0];
if (path == null) return {x:0, y:0};
const loc = (t + theta) % 1;
const rawPt = path.getPointAtLength(loc * path.getTotalLength());
const pt = { x: chart.x.invert(rawPt.x), y: chart.y.invert(rawPt.y) };
const thetaP = (getTheta(pt.x, pt.y) - theta + 1) % 1;
return [(thetaP * 2 - zero + 2) % 2, pt[coord]];
}
function getShape(r, inset, points) {
const shape = 'star';
switch (shape) {
case 'square':
return [[-0.5 + r, 0.5], [-0.5, 0.5 + r], [-0.5 - r, 0.5], [-0.5, 0.5 - r], [-0.5 + r, 0.5]];
case 'star':
const path = [];
for (let i = 0; i < points * 2 + 1; i++) {
const rad = (i % 2 === 0 ? r : r / inset);
const t = Math.PI * 2 / points / 2 * i;
path.push([Math.cos(t) * rad - 0.5, Math.sin(t) * rad + 0.5]);
}
return path;
default:
break;
}
}
setTimeout(render, 300);
</script>
<ink-chart id="squareWave" xlim="[-1, 2]" ylim="[-1, 1]" height="400" width="600" xAxisLocation="hidden" yAxisLocation="hidden">
<ink-chart-path :data="[[-1,0],[2, 0],[],[0, -1], [0, 1]]" stroke="#ddd" strokewidth="2"></ink-chart-path>
<ink-chart-path :data="[[-1, 0.5-r],[2, 0.5-r],[],[-1, 0.5], [2, 0.5],[],[-1, 0.5+r],[2, 0.5+r]]" stroke="#ddd" strokewidth="0.5"></ink-chart-path>
<ink-chart-path :data="[[ 0,-0.5-r],[2,-0.5-r],[],[ 0,-0.5], [2,-0.5],[],[ 0,-0.5+r],[2,-0.5+r]]" stroke="#ddd" strokewidth="0.5"></ink-chart-path>
<ink-chart-path :data="[[-0.5-r,1],[-0.5-r,0],[],[-0.5,1], [-0.5,0],[],[-0.5+r,1],[-0.5+r,0]]" stroke="#ddd" strokewidth="0.5"></ink-chart-path>
<ink-chart-path :data="[[xC, yC], [0, yC]]" stroke="red" strokewidth="1"></ink-chart-path>
<ink-chart-path :data="[[xC, yC], [xC, 0]]" stroke="blue" strokewidth="1"></ink-chart-path>
<ink-chart-eqn eqn="[-Math.cos(t)*(-0.5-r), -Math.sin(t)*(-0.5-r)]" parameterize="t" :domain="[Math.PI, Math.PI*1.5]" stroke="#ddd" strokewidth="0.5"></ink-chart-eqn>
<ink-chart-eqn eqn="[-Math.cos(t)/-2, -Math.sin(t)/-2]" parameterize="t" :domain="[Math.PI, Math.PI*1.5]" stroke="#ddd" strokewidth="0.5"></ink-chart-eqn>
<ink-chart-eqn eqn="[-Math.cos(t)*(-0.5+r), -Math.sin(t)*(-0.5+r)]" parameterize="t" :domain="[Math.PI, Math.PI*1.5]" stroke="#ddd" strokewidth="0.5"></ink-chart-eqn>
<ink-chart-eqn eqn="[-Math.cos(t)*xC, -Math.sin(t)*xC]" parameterize="t" :domain="[Math.PI, Math.PI*1.5]" stroke="blue" strokewidth="1"></ink-chart-eqn>
<!-- <ink-chart-path :data="[[-0.5,0.5], [xC,yC]]" stroke="green" strokewidth="1"></ink-chart-path> -->
<ink-chart-text text="sin-ish(&theta;)" x="1.6" :y=" 0.43-r" fill="red"></ink-chart-text>
<ink-chart-text text="cos-ish(&theta;)" x="1.6" :y="-0.57-r" fill="blue"></ink-chart-text>
<ink-chart-path :data="getShape(r, inset, points)" :visible="!draw" stroke="green" strokewidth="2"></ink-chart-path>
<ink-chart-eqn eqn="getCoord(t, theta, 'y', zeroY, draw)" :samples="draw? 100 : 500" parameterize="t" domain="[0.001, 0.999]" stroke="red" strokewidth="3"></ink-chart-eqn>
<ink-chart-eqn eqn="getCoord(t, theta, 'x', zeroX, draw)" :samples="draw? 100 : 500" parameterize="t" domain="[0.001, 0.999]" stroke="blue" strokewidth="3"></ink-chart-eqn>
<ink-chart-node :x="xC" :y="yC" fill="green" :visible="!draw" :drag="{theta: getTheta(x,y)}"></ink-chart-node>
<ink-chart-path :data="path" :visible="draw" stroke="purple" strokewidth="2" curve="basis" closed="true"></ink-chart-path>
<ink-chart-node :x="uX" :y="uY" :visible="draw" fill="purple" :drag="setPath(x,y)"></ink-chart-node>
<ink-chart-circle :x="xC" :y="yC" fill="black" :visible="draw"></ink-chart-circle>
</ink-chart>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment