moved to multi-file, added some comments
This commit is contained in:
7 files changed
+926
-56
No files matched your search
+178
@@ -0,0 +1,178 @@
|
||||
import * as maths from "./maths.js";
|
||||
|
||||
let uInput = document.getElementById("u");
|
||||
let hInput = document.getElementById("h");
|
||||
let rInput = document.getElementById("r");
|
||||
let rsInput = document.getElementById("rs");
|
||||
let npInput = document.getElementById("np");
|
||||
let outputdiv = document.getElementById("output");
|
||||
let stepInput = document.getElementById("steps");
|
||||
let lenOutput = document.getElementById("len");
|
||||
|
||||
let height = 0;
|
||||
let radius = 0;
|
||||
let spillRadius = 0;
|
||||
let numberOfPanels = 0;
|
||||
|
||||
let multiplier = 1;
|
||||
|
||||
let step = 0.001 * multiplier;
|
||||
// const offset = 3*10**-15 * multiplier;
|
||||
const offset = 4 * 10 ** -5 * multiplier;
|
||||
|
||||
let pointsP = [];
|
||||
let pointsQ = [];
|
||||
let distances = [];
|
||||
|
||||
let panelPoints = [];
|
||||
|
||||
let n = 0;
|
||||
let unit = "px";
|
||||
let strokeWidth = 1;
|
||||
|
||||
// maths
|
||||
|
||||
|
||||
// logic
|
||||
function getValues() {
|
||||
pointsP = [];
|
||||
pointsQ = [];
|
||||
distances = [];
|
||||
panelPoints = [];
|
||||
height = /* /* Math.floor */(parseFloat(hInput.value) * multiplier);
|
||||
radius = /* Math.floor */(parseFloat(rInput.value) * multiplier);
|
||||
spillRadius = /* Math.floor */(parseFloat(rsInput.value) * multiplier);
|
||||
numberOfPanels = /* Math.floor */(parseFloat(npInput.value) * multiplier);
|
||||
step = radius / parseInt(stepInput.value);
|
||||
if (isNaN(spillRadius)) {
|
||||
spillRadius = /* Math.floor */(0.05 * radius);
|
||||
rsInput.value = 0.05 * radius / multiplier;
|
||||
}
|
||||
n = ((radius - spillRadius) / (step - offset)) - 1;
|
||||
console.log(`${height}, ${radius}, ${spillRadius}, ${step}, ${offset}`);
|
||||
}
|
||||
|
||||
function getPoints() {
|
||||
for (let x = spillRadius; x < radius; x += step - offset) {
|
||||
x = maths.approx(x);
|
||||
pointsP.push({
|
||||
x: x,
|
||||
y: maths.f(x, height, radius)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function getPointsOfTangentIntersection() {
|
||||
for (let i = 0; i < n; i++) {
|
||||
console.log(`${i}, ${pointsP[i].x} ${pointsP[i].y}, ${pointsP[i + 1].x} ${pointsP[i+1].y}`);
|
||||
pointsQ.push({
|
||||
x: maths.j(pointsP[i], pointsP[i + 1], height, radius),
|
||||
y: maths.g(maths.j(pointsP[i], pointsP[i + 1], height, radius), pointsP[i + 1], height, radius)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function getDistancesBetweenIntersections() {
|
||||
for (let i = 0; i < n - 1; i++) {
|
||||
distances.push(maths.d(pointsQ[i], pointsQ[i + 1], height, radius));
|
||||
}
|
||||
}
|
||||
|
||||
function generateCoordinates() {
|
||||
let Xi = 0;
|
||||
for (let i = 0; i < n - 2; i++) {
|
||||
Xi += distances[i];
|
||||
let Yi = (Math.PI * pointsQ[i].x) / numberOfPanels;
|
||||
panelPoints.push({
|
||||
x: Xi,
|
||||
y: Yi
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function plotSVG() {
|
||||
let maxY = 0;
|
||||
let maxX = 0;
|
||||
let minX = 1000;
|
||||
panelPoints.forEach((point) => {
|
||||
if (maxY < point.y) {
|
||||
maxY = point.y;
|
||||
}
|
||||
if (minX > point.x) {
|
||||
minX = point.x;
|
||||
}
|
||||
if (maxX < point.x) {
|
||||
maxX = point.x;
|
||||
}
|
||||
})
|
||||
let pointsA = "";
|
||||
let pointsB = "";
|
||||
for (let i = 0; i < panelPoints.length; i++) {
|
||||
let point = panelPoints[i];
|
||||
pointsA += `${maths.approx(point.x)},${(maxY) - maths.approx(point.y)} `;
|
||||
pointsB +=`${maths.approx(point.x)},${maths.approx((point.y + maxY))} `;
|
||||
}
|
||||
outputdiv.innerHTML = `
|
||||
<svg width="297mm"
|
||||
height="210mm"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="layer1">
|
||||
<line
|
||||
x1="${maths.approx(panelPoints[0].x)}${unit}"
|
||||
x2="${panelPoints[0].x}${unit}"
|
||||
y1="${maxY - maths.approx(panelPoints[0].y)}${unit}"
|
||||
y2="${maths.approx((panelPoints[0].y + maxY))}${unit}"
|
||||
fill="none"
|
||||
stroke="black"
|
||||
stroke-width="${strokeWidth}"
|
||||
/>
|
||||
<line
|
||||
x1="${maths.approx(panelPoints[panelPoints.length - 1].x)}${unit}"
|
||||
x2="${panelPoints[panelPoints.length - 1].x}${unit}"
|
||||
y1="${maxY - maths.approx(panelPoints[panelPoints.length - 1].y)}${unit}"
|
||||
y2="${maths.approx((panelPoints[panelPoints.length - 1].y + maxY))}${unit}"
|
||||
fill="none"
|
||||
stroke="black"
|
||||
stroke-width="${strokeWidth}"
|
||||
/>
|
||||
<line
|
||||
x1="${maths.approx(panelPoints[0].x)}${unit}"
|
||||
x2="${panelPoints[panelPoints.length - 1].x}${unit}"
|
||||
y1="${(maxY - maths.approx(panelPoints[0].y) + maths.approx((panelPoints[0].y + maxY))) / 2}${unit}"
|
||||
y2="${(maxY - maths.approx(panelPoints[panelPoints.length - 1].y) + maths.approx((panelPoints[panelPoints.length - 1].y + maxY))) / 2}${unit}"
|
||||
fill="none"
|
||||
stroke="black"
|
||||
stroke-width="${strokeWidth}"
|
||||
/>
|
||||
<polyline
|
||||
points="${pointsA}"
|
||||
fill="none"
|
||||
stroke="black"
|
||||
stroke-width="${strokeWidth}"
|
||||
/>
|
||||
<polyline
|
||||
points="${pointsB}"
|
||||
fill="none"
|
||||
stroke="black"
|
||||
stroke-width="${strokeWidth}"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
`;
|
||||
lenOutput.innerText = `Recommended length: ${maths.approx(maxX - minX)} ${unit}`;
|
||||
}
|
||||
|
||||
|
||||
// main func
|
||||
function generatePanel() {
|
||||
unit=uInput.value;
|
||||
getValues();
|
||||
getPoints();
|
||||
getPointsOfTangentIntersection();
|
||||
getDistancesBetweenIntersections();
|
||||
generateCoordinates();
|
||||
plotSVG();
|
||||
}
|
||||
|
||||
document.getElementById("generate").addEventListener("click", () => generatePanel());
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
import { sanitiseArguments } from "./utils";
|
||||
|
||||
let accuracy = import.meta.env.VITE_ACCURACY;
|
||||
|
||||
export function approx(n) {
|
||||
return Math.round(n * (10 ** accuracy)) / (10 ** accuracy);
|
||||
}
|
||||
|
||||
// calculate y co-ordinate of point on ellipse at x
|
||||
// x: x co-ordinate
|
||||
// h: height of ellipse
|
||||
// r: radius of spill hole
|
||||
export function f(x, h, r) {
|
||||
sanitiseArguments(x,h,r)
|
||||
let res = approx(h * Math.sqrt((1 - (Math.pow(x, 2) / Math.pow(r, 2)))));
|
||||
console.log(`f(${x} ${h} ${r}) ${res}`);
|
||||
return res;
|
||||
}
|
||||
|
||||
// calculate the gradient of the ellipse at a given point x
|
||||
// x: x co-ordinate of point
|
||||
// h: height of ellipse
|
||||
// r: radius of spill hole
|
||||
export function fprime(x, h, r) {
|
||||
sanitiseArguments(x,h,r)
|
||||
let res = approx(-1 * ((Math.pow(h, 2) * x) / (Math.pow(r, 2) * f(x, h, r))));
|
||||
console.log(`fprime (${x} ${h} ${r}) ${res}`);
|
||||
return res;
|
||||
}
|
||||
|
||||
// calculate the y co-ordinate of the point on the tangent at P to an ellipse at x
|
||||
// x: x co-ordinate along tangent
|
||||
// P: (x,y) for the point on the ellipse the tangent is from
|
||||
// h: height of ellipse
|
||||
// r: radius of spill hole
|
||||
export function g(x, P, h, r) {
|
||||
sanitiseArguments(x,P.x, P.y,h,r)
|
||||
let res = approx(fprime(x, h, r) * (x - P.x) + P.y);
|
||||
console.log(`g (${x} {${P.x} ${P.y}} ${h} ${r}) ${res}`);
|
||||
return res;
|
||||
}
|
||||
|
||||
// find the intersection between two tangents of an ellipse
|
||||
// A: (x,y) for the point of the ellipse for the first tangent
|
||||
// B: (x,y) for the point of the ellipse for the second tangent
|
||||
// h: height of the ellipse
|
||||
// r: radius of the spill hole
|
||||
export function j(A, B, h, r) {
|
||||
sanitiseArguments(A.x, A.y, B.x, B.y, h,r)
|
||||
let res = approx(A.x * fprime(A.x, h, r) - B.x * fprime(B.x, h, r) - A.y + B.y) / (fprime(A.x, h, r) - fprime(B.x, h, r));
|
||||
console.log(`j ({${A.x} ${A.y}} {${B.x} ${B.y}} ${h} ${r}) ${res}`);
|
||||
return res;
|
||||
}
|
||||
|
||||
// find the distance between two points
|
||||
// A: (x,y) the first point
|
||||
// B: (x,y) the second point
|
||||
export function d(A, B) {
|
||||
sanitiseArguments(A.x, A.y, B.x, B.y)
|
||||
let res = approx(Math.sqrt(Math.pow(A.x - B.x, 2) + Math.pow(A.y - B.y, 2)));
|
||||
console.log(`d ({${A.x} ${A.y}} {${B.x} ${B.y}}) ${res}`);
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
export function sanitiseArguments(...args) {
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
if (args[i] == undefined || args[i] == NaN) {
|
||||
throw new Error(`bad argument: ${args}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user