Tengo una longitud de línea que estoy dividiendo en dos segmentos. En lugar de escupir por la mitad o usar algún otro valor arbitrario, deseo usar Phi, o la proporción áurea, para determinar la longitud de cada segmento.
Por ejemplo, dado un valor de altura de 100, necesito el retorno de 61,8 y 38,2.
En este caso, estoy programando una forma SVG generada dinámicamente usando JavaScript. Se utiliza un formulario para proporcionar las entradas, por ejemplo, la altura de la forma. Hay esquinas en la parte inferior que usan curvas Bezier . Deseo comenzar la curva de Bézier en un punto a lo largo del lado determinado por la proporción áurea, o "phi", que es aproximadamente 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>
Dos fórmulas de proporción áurea (o "phi", que es una proporción de aproximadamente 1,618), de una línea formada por los segmentos de línea a y b, consecutivamente, son:
// ab // X---------X-----X a/b = 1.618... // and (a + b) / a = 1.618...
Al no tener a ni b, pero tener la longitud total de la línea, la segunda relación se usa para determinar primero a, luego 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
Usando las dos últimas ecuaciones, escriba una función Javascript que acepte la longitud total de la línea:
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 }
Devoluciones:
> getPhiSegs(100) > { phi_major: 61.8, phi_minor: 38.2 }
Usando la función getPhiSegs
para definir una ruta SVG:
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 )
En primer lugar, debe resolver la ecuación que define phi. De wikipedia:
const phi = (1 + Math.sqrt(5)) / 2; console.log(phi); const getSegments=(h)=>{return {'a': h/phi, 'b': hh/phi};} console.log(getSegments(100));
Entonces, en el contexto de su código existente:
const phi = (1 + Math.sqrt(5)) / 2; const getSegments=(h)=>{return {'a': h/phi, 'b': hh/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>