I have a line length I'm dividing into two segments. Rather than spit in half or use some other arbitrary value, I wish to use Phi, or the Golden Ratio, to determine the length of each segment.
For example, given a height value of 100, I need the return of 61.8 and 38.2.
In this case I'm programming a dynamically generated SVG shape using JavaScript. A form is used to provide the inputs, for example height of the shape. There are corners at the bottom that use Bezier curves. I wish to start the bezier curve at a point along the side determined by the Golden Ratio, or "phi" which is approximately 1.618.
<svg width="600" height="600" viewBox="0 0 0 0">
<path d="" />
</svg>
<script>
let height = 100
let vertical = 38.2
let corner = 61.8
// d = "m 300 300 v 38.2 c 0 100 38.2 100 100 100"
document.querySelector('path').setAttribute("d",
"m 300 300 v " + vertical + " c 0 " + corner + " " + vertical + " " + corner + " " + corner + " " + corner
)
</script>
Two Golden Ratio (or "phi", which is a ratio of approximately 1.618) formulas—of a line made up of line segments a and b, consecutively—are:
// a b
// X---------X-----X
a/b = 1.618...
// and
(a + b) / a = 1.618...
Having neither a nor b, but having the total line length, the second ratio is used to determine first a, then b:
// 1) Starting with formula:
(a + b) / a = 1.618...
// 2) Rename (a + b) to represent the known value:
(total_line_length) / a = 1.618...
// 3) Isolate variable a:
total_line_length / a * a = a * 1.618... // multiply each side by a
total_line_length = a * 1.618...
total_line_length / 1.618... = a * 1.618... / 1.618... // divide each side by 1.618...
a = total_line_length / 1.618...
// 4) Get b:
b = total_line_length - a
Using the last two equations write a Javascript function that accepts the total line length:
function getPhiSegs (total_line_length) {
let major = total_line_length / 1.61803398874989484820
let minor = total_line_length - major
return {"phi_major": rndH(major), "phi_minor": rndH(minor)}
}
function rndH(val) { // round value to nearest hundreth
return Math.round(val * 100) / 100
}
Returns:
> getPhiSegs(100)
> { phi_major: 61.8, phi_minor: 38.2 }
Using getPhiSegs
function to define an SVG path:
let height = document.forms[0].elements['height'].value
let height_phi_segments = getPhiSegs(height)
let vertical = height_phi_segments.phi_minor
let corner = height_phi_segments.phi_major
document.querySelector('path').setAttribute("d",
"m 300 300 v " + vertical + " c 0 " + corner + " " + vertical + " " + corner + " " + corner + " " + corner
)
You need to solve the equation that defines phi, first of all. From wikipedia:
const phi = (1 + Math.sqrt(5)) / 2;
console.log(phi);
const getSegments=(h)=>{return {'a': h/phi, 'b': h-h/phi};}
console.log(getSegments(100));
So in context of your existing code:
const phi = (1 + Math.sqrt(5)) / 2;
const getSegments=(h)=>{return {'a': h/phi, 'b': h-h/phi};}
let height = 100;
let segments = getSegments(height);
let pathDef =
`m 300 300 v ${segments.b}
c 0 ${segments.a} ${segments.b}
${segments.a} ${segments.a} ${segments.a}`;
console.log(pathDef);
document.querySelector('path').setAttribute("d", pathDef);
<svg width="12cm" height="4cm"
viewBox="0 0 300 600"
xmlns="http://www.w3.org/2000/svg"
version="1.1"
>
<path d=""
fill="none" stroke="blue"
stroke-width="20"
/>
</svg>