?
This commit is contained in:
10
.idea/.gitignore
generated
vendored
Normal file
10
.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Ignored default folder with query files
|
||||
/queries/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
8
.idea/Parachute-SVG-Generator.iml
generated
Normal file
8
.idea/Parachute-SVG-Generator.iml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/Parachute-SVG-Generator.iml" filepath="$PROJECT_DIR$/.idea/Parachute-SVG-Generator.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
12
index.html
12
index.html
@@ -7,15 +7,25 @@
|
||||
<h1>Parachute Panel Generator</h1>
|
||||
<p>Generate the SVG outline of a parachute panel for an elliptical parachute. Find out more <a>here</a>.</p>
|
||||
<br>
|
||||
<label for="u">Units:</label>
|
||||
<select id="u">
|
||||
<option value="px">Pixels</option>
|
||||
<option value="mm">Millimetres</option>
|
||||
<option value="cm">Centimetres</option>
|
||||
<option value="in">Inches</option>
|
||||
</select> <br>
|
||||
<label for="h">Height of parachute (h):</label>
|
||||
<input type="number" id="h" min="0"/><br>
|
||||
<label for="r">Radius of parachute (r):</label>
|
||||
<input type="number" id="r" min="0"/><br>
|
||||
<label for="rs">Radius of spill hole (r<sub>s</sub>): (leave blank to use 0.05r)</label>
|
||||
<label for="rs">Radius of spill hole (r<sub>s</sub>): (leave blank to use 5% of the radius)</label>
|
||||
<input type="number" id="rs" /><br>
|
||||
<label for="np">Number of panels (n<sub>p</sub>): </label>
|
||||
<input type="number" id="np" min="3" ><br>
|
||||
<label for="steps">Number of steps: </label>
|
||||
<input type="number" id="steps" min="10" /><br>
|
||||
<button onclick="generatePanel()">Generate!</button>
|
||||
<p id="len"></p>
|
||||
<div id="output"></div>
|
||||
<script src="index.js" lang="js"></script>
|
||||
</body>
|
||||
|
||||
132
index.js
132
index.js
@@ -1,8 +1,11 @@
|
||||
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;
|
||||
@@ -12,9 +15,9 @@ let numberOfPanels = 0;
|
||||
let multiplier = 1;
|
||||
let accuracy = 8;
|
||||
|
||||
const step = 0.001 * multiplier;
|
||||
let step = 0.001 * multiplier;
|
||||
// const offset = 3*10**-15 * multiplier;
|
||||
const offset = 4*10**-5 * multiplier;
|
||||
const offset = 4 * 10 ** -5 * multiplier;
|
||||
|
||||
let pointsP = [];
|
||||
let pointsQ = [];
|
||||
@@ -23,38 +26,40 @@ let distances = [];
|
||||
let panelPoints = [];
|
||||
|
||||
let n = 0;
|
||||
let unit = "px";
|
||||
let strokeWidth = 1;
|
||||
|
||||
// maths
|
||||
function approx(x) {
|
||||
return Math.round(x*(10**accuracy))/(10**accuracy);
|
||||
function approx(n) {
|
||||
return Math.round(n * (10 ** accuracy)) / (10 ** accuracy);
|
||||
}
|
||||
|
||||
function f(x) {
|
||||
res = approx(height * Math.sqrt((1-(Math.pow(x,2)/Math.pow(radius,2)))));
|
||||
res = approx(height * Math.sqrt((1 - (Math.pow(x, 2) / Math.pow(radius, 2)))));
|
||||
console.log(`f ${x} ${res}`);
|
||||
return res;
|
||||
}
|
||||
|
||||
function fprime(x) {
|
||||
res = approx(-1*((Math.pow(height,2)*x)/(Math.pow(radius,2)*f(x))));
|
||||
res = approx(-1 * ((Math.pow(height, 2) * x) / (Math.pow(radius, 2) * f(x))));
|
||||
console.log(`fprime ${x} ${res}`);
|
||||
return res;
|
||||
}
|
||||
|
||||
function g(x, P) {
|
||||
res = approx(fprime(x)*(x-P.x)+P.y);
|
||||
res = approx(fprime(x) * (x - P.x) + P.y);
|
||||
console.log(`g ${x} ${P.x} ${P.y} ${res}`);
|
||||
return res;
|
||||
}
|
||||
|
||||
function j(A, B) {
|
||||
res = approx(A.x*fprime(A.x)-B.x*fprime(B.x)-A.y+B.y)/(fprime(A.x)-fprime(B.x));
|
||||
res = approx(A.x * fprime(A.x) - B.x * fprime(B.x) - A.y + B.y) / (fprime(A.x) - fprime(B.x));
|
||||
console.log(`j ${A.x} ${A.y} ${B.x} ${B.y} ${res}`);
|
||||
return res;
|
||||
}
|
||||
|
||||
function d(A, B) {
|
||||
res = approx(Math.sqrt(Math.pow(A.x-B.x,2)+Math.pow(A.y-B.y,2)));
|
||||
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;
|
||||
}
|
||||
@@ -65,21 +70,22 @@ function getValues() {
|
||||
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);
|
||||
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;
|
||||
spillRadius = /* Math.floor */(0.05 * radius);
|
||||
rsInput.value = 0.05 * radius / multiplier;
|
||||
}
|
||||
n = ((radius-spillRadius)/(step-offset))-1;
|
||||
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=approx(x);
|
||||
for (let x = spillRadius; x < radius; x += step - offset) {
|
||||
x = approx(x);
|
||||
pointsP.push({
|
||||
x: x,
|
||||
y: f(x)
|
||||
@@ -89,25 +95,25 @@ function getPoints() {
|
||||
|
||||
function getPointsOfTangentIntersection() {
|
||||
for (let i = 0; i < n; i++) {
|
||||
console.log(`${i}, ${pointsP[i]}, ${pointsP[i+1]}`);
|
||||
console.log(`${i}, ${pointsP[i]}, ${pointsP[i + 1]}`);
|
||||
pointsQ.push({
|
||||
x: j(pointsP[i], pointsP[i+1]),
|
||||
y: g(j(pointsP[i], pointsP[i+1]), pointsP[i+1])
|
||||
x: j(pointsP[i], pointsP[i + 1]),
|
||||
y: g(j(pointsP[i], pointsP[i + 1]), pointsP[i + 1])
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function getDistancesBetweenIntersections() {
|
||||
for (let i = 0; i < n-1; i++) {
|
||||
distances.push(d(pointsQ[i], pointsQ[i+1]));
|
||||
for (let i = 0; i < n - 1; i++) {
|
||||
distances.push(d(pointsQ[i], pointsQ[i + 1]));
|
||||
}
|
||||
}
|
||||
|
||||
function generateCoordinates() {
|
||||
let Xi = 0;
|
||||
for (let i = 0; i < n-2; i++) {
|
||||
Xi+=distances[i];
|
||||
Yi=(Math.PI*pointsQ[i].x)/numberOfPanels;
|
||||
for (let i = 0; i < n - 2; i++) {
|
||||
Xi += distances[i];
|
||||
Yi = (Math.PI * pointsQ[i].x) / numberOfPanels;
|
||||
panelPoints.push({
|
||||
x: Xi,
|
||||
y: Yi
|
||||
@@ -117,32 +123,80 @@ function generateCoordinates() {
|
||||
|
||||
function plotSVG() {
|
||||
let maxY = 0;
|
||||
let maxX = 0;
|
||||
let minX = 1000;
|
||||
panelPoints.forEach((point) => {
|
||||
if (maxY < point.y) {
|
||||
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 pointsA = "";
|
||||
let pointsB = "";
|
||||
for (let i = 0; i < panelPoints.length; i++) {
|
||||
let point = panelPoints[i];
|
||||
pointsA.push(`${approx(point.x*10)},${(maxY*10)-approx(point.y*10)}`)
|
||||
pointsB.push(`${approx(point.x*10)},${approx((point.y+maxY)*10)}`);
|
||||
pointsA += `${approx(point.x)},${(maxY) - approx(point.y)} `;
|
||||
pointsB +=`${approx(point.x)},${approx((point.y + maxY))} `;
|
||||
}
|
||||
outputdiv.innerHTML = `
|
||||
<svg viewBox="0 0 100 200" xmlns="http://www.w3.org/2000/svg">
|
||||
<line x1="${approx(panelPoints[0].x*10)}" x2="${panelPoints[0].x*10}" y1="${maxY*10-approx(panelPoints[0].y*10)}" y2="${approx((panelPoints[0].y+maxY)*10)}" fill="none" stroke="black" stroke-width="0.05" />
|
||||
<line x1="${approx(panelPoints[panelPoints.length-1].x*10)}" x2="${panelPoints[panelPoints.length-1].x*10}" y1="${maxY*10-approx(panelPoints[panelPoints.length-1].y*10)}" y2="${approx((panelPoints[panelPoints.length-1].y+maxY)*10)}" fill="none" stroke="black" stroke-width="0.05" />
|
||||
<line x1="${approx(panelPoints[0].x*10)}" x2="${panelPoints[panelPoints.length-1].x*10}" y1="${(maxY*10-approx(panelPoints[0].y*10)+approx((panelPoints[0].y+maxY)*10))/2}" y2="${(maxY*10-approx(panelPoints[panelPoints.length-1].y*10)+approx((panelPoints[panelPoints.length-1].y+maxY)*10))/2}" fill="none" stroke="black" stroke-width="0.05" />
|
||||
<polyline points="${pointsA}" fill="none" stroke="black" stroke-width="0.05" />
|
||||
<polyline points="${pointsB}" fill="none" stroke="black" stroke-width="0.05" />
|
||||
<svg width="297mm"
|
||||
height="210mm"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="layer1">
|
||||
<line
|
||||
x1="${approx(panelPoints[0].x)}${unit}"
|
||||
x2="${panelPoints[0].x}${unit}"
|
||||
y1="${maxY - approx(panelPoints[0].y)}${unit}"
|
||||
y2="${approx((panelPoints[0].y + maxY))}${unit}"
|
||||
fill="none"
|
||||
stroke="black"
|
||||
stroke-width="${strokeWidth}"
|
||||
/>
|
||||
<line
|
||||
x1="${approx(panelPoints[panelPoints.length - 1].x)}${unit}"
|
||||
x2="${panelPoints[panelPoints.length - 1].x}${unit}"
|
||||
y1="${maxY - approx(panelPoints[panelPoints.length - 1].y)}${unit}"
|
||||
y2="${approx((panelPoints[panelPoints.length - 1].y + maxY))}${unit}"
|
||||
fill="none"
|
||||
stroke="black"
|
||||
stroke-width="${strokeWidth}"
|
||||
/>
|
||||
<line
|
||||
x1="${approx(panelPoints[0].x)}${unit}"
|
||||
x2="${panelPoints[panelPoints.length - 1].x}${unit}"
|
||||
y1="${(maxY - approx(panelPoints[0].y) + approx((panelPoints[0].y + maxY))) / 2}${unit}"
|
||||
y2="${(maxY - approx(panelPoints[panelPoints.length - 1].y) + 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: ${approx(maxX - minX)} ${unit}`;
|
||||
}
|
||||
|
||||
|
||||
// main func
|
||||
function generatePanel() {
|
||||
unit=uInput.value;
|
||||
getValues();
|
||||
getPoints();
|
||||
getPointsOfTangentIntersection();
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"url": "git@git.emaker.limited:chopster44/Parachute-SVG-Generator.git"
|
||||
},
|
||||
"license": "SEE LICENSE IN LICENSE",
|
||||
"author": "chopster44",
|
||||
"author": "Oscar Giacalone",
|
||||
"type": "commonjs",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
||||
Reference in New Issue
Block a user