Skip to content

Instantly share code, notes, and snippets.

@P-nutsK
Created February 10, 2026 10:35
Show Gist options
  • Select an option

  • Save P-nutsK/98fb0441452f9b52221f842be1377b3f to your computer and use it in GitHub Desktop.

Select an option

Save P-nutsK/98fb0441452f9b52221f842be1377b3f to your computer and use it in GitHub Desktop.
import { Project } from "hikkaku";
import {
add,
addToList,
callProcedure,
changeVariableBy,
defineProcedure,
deleteAllOfList,
divide,
equals,
eraseAll,
forEach,
forever,
getItemOfList,
getMouseDown,
getMouseX,
getMouseY,
getVariable,
gotoXY,
hide,
ifElse,
ifThen,
lengthOfList,
mathop,
multiply,
penDown,
penUp,
procedureLabel,
setPenColorTo,
setPenSizeTo,
setRotationStyle,
setVariableTo,
subtract,
whenFlagClicked,
} from "hikkaku/blocks";
const project = new Project();
const pen = project.createSprite("pen");
const baseX = pen.createList("baseX", []);
const baseY = pen.createList("baseY", []);
const baseZ = pen.createList("baseZ", []);
const baseW = pen.createList("baseW", []);
const screenX = pen.createList("screenX", []);
const screenY = pen.createList("screenY", []);
const edgeA = pen.createList("edgeA", []);
const edgeB = pen.createList("edgeB", []);
const angle = pen.createVariable("angle", 0);
const angle2 = pen.createVariable("angle2", 0);
const angle3 = pen.createVariable("angle3", 0);
const dragX = pen.createVariable("dragX", 0);
const dragY = pen.createVariable("dragY", 0);
const lastMouseX = pen.createVariable("lastMouseX", 0);
const lastMouseY = pen.createVariable("lastMouseY", 0);
const mouseDx = pen.createVariable("mouseDx", 0);
const mouseDy = pen.createVariable("mouseDy", 0);
const dragging = pen.createVariable("dragging", 0);
const velX = pen.createVariable("velX", 0);
const velY = pen.createVariable("velY", 0);
const sinA = pen.createVariable("sinA", 0);
const cosA = pen.createVariable("cosA", 0);
const sinB = pen.createVariable("sinB", 0);
const cosB = pen.createVariable("cosB", 0);
const sinC = pen.createVariable("sinC", 0);
const cosC = pen.createVariable("cosC", 0);
const sinD = pen.createVariable("sinD", 0);
const cosD = pen.createVariable("cosD", 0);
const idx = pen.createVariable("idx", 1);
const edgeIdx = pen.createVariable("edgeIdx", 1);
const x = pen.createVariable("x", 0);
const y = pen.createVariable("y", 0);
const z = pen.createVariable("z", 0);
const w = pen.createVariable("w", 0);
const x1 = pen.createVariable("x1", 0);
const y1 = pen.createVariable("y1", 0);
const z1 = pen.createVariable("z1", 0);
const w1 = pen.createVariable("w1", 0);
const w2 = pen.createVariable("w2", 0);
const x2 = pen.createVariable("x2", 0);
const y2 = pen.createVariable("y2", 0);
const z2 = pen.createVariable("z2", 0);
const x3 = pen.createVariable("x3", 0);
const y3 = pen.createVariable("y3", 0);
const z3 = pen.createVariable("z3", 0);
const z4 = pen.createVariable("z4", 0);
const scale3 = pen.createVariable("scale3", 0);
const scale2 = pen.createVariable("scale2", 0);
const ax = pen.createVariable("ax", 0);
const ay = pen.createVariable("ay", 0);
const bx = pen.createVariable("bx", 0);
const by = pen.createVariable("by", 0);
const aIdx = pen.createVariable("aIdx", 0);
const bIdx = pen.createVariable("bIdx", 0);
const stepProcCode = "1step";
const vertexData: Array<[number, number, number, number]> = [];
for (const vx of [-1, 1]) {
for (const vy of [-1, 1]) {
for (const vz of [-1, 1]) {
for (const vw of [-1, 1]) {
vertexData.push([vx, vy, vz, vw]);
}
}
}
}
const edgePairs: Array<[number, number]> = [];
for (let i = 0; i < vertexData.length; i += 1) {
for (let j = i + 1; j < vertexData.length; j += 1) {
const a = vertexData[i];
const b = vertexData[j];
let diff = 0;
for (let k = 0; k < 4; k += 1) {
if (a[k] !== b[k]) {
diff += 1;
}
}
if (diff === 1) {
edgePairs.push([i + 1, j + 1]);
}
}
}
pen.run(() => {
defineProcedure(
[procedureLabel(stepProcCode)],
() => {
ifElse(
getMouseDown(),
() => {
ifThen(equals(getVariable(dragging), 0), () => {
setVariableTo(lastMouseX, getMouseX());
setVariableTo(lastMouseY, getMouseY());
setVariableTo(dragging, 1);
});
setVariableTo(mouseDx, subtract(getMouseX(), getVariable(lastMouseX)));
setVariableTo(mouseDy, subtract(getMouseY(), getVariable(lastMouseY)));
setVariableTo(lastMouseX, getMouseX());
setVariableTo(lastMouseY, getMouseY());
setVariableTo(velX, multiply(getVariable(mouseDx), 0.2));
setVariableTo(velY, multiply(getVariable(mouseDy), 0.2));
changeVariableBy(dragX, getVariable(velX));
changeVariableBy(dragY, getVariable(velY));
},
() => {
setVariableTo(dragging, 0);
setVariableTo(velX, multiply(getVariable(velX), 0.92));
setVariableTo(velY, multiply(getVariable(velY), 0.92));
changeVariableBy(dragX, getVariable(velX));
changeVariableBy(dragY, getVariable(velY));
},
);
ifThen(getMouseDown(), () => {
changeVariableBy(angle, 0);
});
ifThen(equals(getMouseDown(), 0), () => {
changeVariableBy(angle, 1.5);
});
setVariableTo(angle2, add(add(getVariable(angle), 35), getVariable(dragY)));
setVariableTo(angle3, add(add(getVariable(angle), 15), getVariable(dragX)));
setVariableTo(sinA, mathop("sin", add(getVariable(angle), getVariable(dragX))));
setVariableTo(cosA, mathop("cos", add(getVariable(angle), getVariable(dragX))));
setVariableTo(sinB, mathop("sin", getVariable(angle2)));
setVariableTo(cosB, mathop("cos", getVariable(angle2)));
setVariableTo(sinC, mathop("sin", getVariable(angle3)));
setVariableTo(cosC, mathop("cos", getVariable(angle3)));
setVariableTo(sinD, mathop("sin", getVariable(angle2)));
setVariableTo(cosD, mathop("cos", getVariable(angle2)));
eraseAll();
deleteAllOfList(screenX);
deleteAllOfList(screenY);
forEach(idx, 16, () => {
setVariableTo(x, getItemOfList(baseX, getVariable(idx)));
setVariableTo(y, getItemOfList(baseY, getVariable(idx)));
setVariableTo(z, getItemOfList(baseZ, getVariable(idx)));
setVariableTo(w, getItemOfList(baseW, getVariable(idx)));
setVariableTo(
x1,
subtract(multiply(getVariable(x), getVariable(cosA)), multiply(getVariable(w), getVariable(sinA))),
);
setVariableTo(
w1,
add(multiply(getVariable(x), getVariable(sinA)), multiply(getVariable(w), getVariable(cosA))),
);
setVariableTo(
y1,
subtract(multiply(getVariable(y), getVariable(cosB)), multiply(getVariable(w1), getVariable(sinB))),
);
setVariableTo(
w2,
add(multiply(getVariable(y), getVariable(sinB)), multiply(getVariable(w1), getVariable(cosB))),
);
setVariableTo(z1, getVariable(z));
setVariableTo(scale3, divide(3.5, subtract(3.5, getVariable(w2))));
setVariableTo(x2, multiply(getVariable(x1), getVariable(scale3)));
setVariableTo(y2, multiply(getVariable(y1), getVariable(scale3)));
setVariableTo(z2, multiply(getVariable(z1), getVariable(scale3)));
setVariableTo(
x3,
add(multiply(getVariable(x2), getVariable(cosC)), multiply(getVariable(z2), getVariable(sinC))),
);
setVariableTo(
z3,
add(
multiply(multiply(getVariable(x2), -1), getVariable(sinC)),
multiply(getVariable(z2), getVariable(cosC)),
),
);
setVariableTo(
y3,
subtract(
multiply(getVariable(y2), getVariable(cosD)),
multiply(getVariable(z3), getVariable(sinD)),
),
);
setVariableTo(
z4,
add(multiply(getVariable(y2), getVariable(sinD)), multiply(getVariable(z3), getVariable(cosD))),
);
setVariableTo(scale2, divide(7, subtract(7, getVariable(z4))));
addToList(screenX, multiply(multiply(getVariable(x3), getVariable(scale2)), 70));
addToList(screenY, multiply(multiply(getVariable(y3), getVariable(scale2)), 70));
});
forEach(edgeIdx, lengthOfList(edgeA), () => {
setVariableTo(aIdx, getItemOfList(edgeA, getVariable(edgeIdx)));
setVariableTo(bIdx, getItemOfList(edgeB, getVariable(edgeIdx)));
setVariableTo(ax, getItemOfList(screenX, getVariable(aIdx)));
setVariableTo(ay, getItemOfList(screenY, getVariable(aIdx)));
setVariableTo(bx, getItemOfList(screenX, getVariable(bIdx)));
setVariableTo(by, getItemOfList(screenY, getVariable(bIdx)));
penUp();
gotoXY(getVariable(ax), getVariable(ay));
penDown();
gotoXY(getVariable(bx), getVariable(by));
penUp();
});
},
true,
);
whenFlagClicked(() => {
hide();
setRotationStyle("don't rotate");
setPenColorTo("#00d2ff");
setPenSizeTo(2);
penUp();
deleteAllOfList(baseX);
deleteAllOfList(baseY);
deleteAllOfList(baseZ);
deleteAllOfList(baseW);
deleteAllOfList(edgeA);
deleteAllOfList(edgeB);
for (const [vx, vy, vz, vw] of vertexData) {
addToList(baseX, vx);
addToList(baseY, vy);
addToList(baseZ, vz);
addToList(baseW, vw);
}
for (const [ea, eb] of edgePairs) {
addToList(edgeA, ea);
addToList(edgeB, eb);
}
forever(() => {
callProcedure(stepProcCode, [], {}, true);
});
});
});
export default project;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment