2012-01-07 14 views
6

Suponiendo que tengo funciones como x² o 2x + 3x², ¿cómo se hace para crear una ruta SVG que se ajuste a estas funciones?Ajusta una curva SVG a un polinomio

Desde mi limitada comprensión de SVG y Bezier curvas creo Busco para es una técnica sencilla para construir los puntos de control de Bézier que aseguren que la gráfica resultante se ajusta a la función dada. Puede asumir de manera segura (si aún no lo ha adivinado) que soy un novato en la programación de gráficos. Sé que los marcos como gnuplot pueden realizar este tipo de interpolación, pero estoy buscando más información sobre cómo hacerlo a mano usando SVG y JavaScript.

EDIT: Un ajuste exacto no es un requisito estricto, pero el gráfico resultante tiene que ser razonablemente preciso (con fines didácticos).

+0

No estoy seguro de si se puede * exactamente * describir un polinomio con una curva de Bezier de el mismo grado – CodesInChaos

+0

@CodeInChaos excelentes comentarios, por curiosidad, ¿cómo las personas grafican un polinomio con SVG ?, lo he visto pero no estoy seguro de cómo las personas pasan de una función a otra. El ajuste exacto no es un requisito estricto, aunque su causa debe ser razonablemente precisa. –

+0

Supongo que grafican como cualquier otra función: calcule el valor de la función en muchos puntos a lo largo de la curva (1000 o más) y luego ajuste una función a través de ella. Es el caso más simple con líneas, pero sin duda se verá mejor con curvas bézier de mayor grado, pero no recuerdo una forma conveniente de calcular los puntos de control. – CodesInChaos

Respuesta

8
<?xml version="1.0" standalone="no"?> 

SVG proporciona curvas de Bézier de órdenes 2 y 3, que debe ser lo suficientemente bueno para polinomios cuadráticos y cúbicos.

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
    "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 
<svg width="20cm" height="20cm" viewBox="0 0 1000 1000" 
    xmlns="http://www.w3.org/2000/svg" version="1.1"> 
    <style type="text/css"><![CDATA[ 
    .axis { fill: none; stroke: black; stroke-width: 3; } 
    .tick { fill: none; stroke: black; stroke-width: 1; } 
    .fun1 { fill: none; stroke: blue; stroke-width: 2; } 
    .fun2 { fill: none; stroke: red; stroke-width: 2; } 
    ]]></style> 
    <polyline class="axis" points="0,500 1000,500" /> 
    <polyline class="tick" points="0,490 0,510" /> 
    <polyline class="tick" points="100,490 100,510" /> 
    <polyline class="tick" points="200,490 200,510" /> 
    <polyline class="tick" points="300,490 300,510" /> 
    <polyline class="tick" points="400,490 400,510" /> 
    <polyline class="tick" points="600,490 600,510" /> 
    <polyline class="tick" points="700,490 700,510" /> 
    <polyline class="tick" points="800,490 800,510" /> 
    <polyline class="tick" points="900,490 900,510" /> 
    <polyline class="tick" points="1000,490 1000,510" /> 
    <polyline class="axis" points="500,0 500,1000" /> 
    <polyline class="tick" points="490,0 510,0" /> 
    <polyline class="tick" points="490,100 510,100" /> 
    <polyline class="tick" points="490,200 510,200" /> 
    <polyline class="tick" points="490,300 510,300" /> 
    <polyline class="tick" points="490,400 510,400" /> 
    <polyline class="tick" points="490,600 510,600" /> 
    <polyline class="tick" points="490,700 510,700" /> 
    <polyline class="tick" points="490,800 510,800" /> 
    <polyline class="tick" points="490,900 510,900" /> 
    <polyline class="tick" points="490,1000 510,1000" /> 

Take y = x² - 4, con puntos finales (-3, 5) y (3, 5); las tangentes son y = -6x - 13 ey = 6x - 13. Coloque el punto de control Q en ambas tangentes, en (0, -13). Esto debería funcionar fácilmente para cualquier cuadrático.

<path class="fun1" d="M200,0 Q500,1800 800,0" /> 

Cubics son un poco tricker. Con y = (x³ - 9x)/16 desde (-5, -5) hasta (5, 5), las tangentes son y = (33x + 125)/8 ey = (33x - 125)/8. Al ver eso la curva debe pasar (0, 0) con pendiente -9/16, es un cálculo simple para encontrar C puntos de control (-5/3, 35/4) y (5/3, 35/4). Probablemente no sea factible a mano la mayor parte del tiempo, pero creo que este enfoque debería ser numéricamente factible para cualquier otra unidad cúbica: dos variables para determinar a qué distancia de cada tangente se encuentran los puntos de control y dos restricciones para un punto y dirección particular.

<path class="fun2" d="M0,1000 C333,-375 667,1375 1000,0" /> 

(Animated Bézier Curves fue muy útil cuando estaba trabajando a cabo.)

</svg> 

+0

Fantástica respuesta. ¿Estoy en lo correcto al observar que no hay una generalización para polinomios de orden superior (que no sea unir una tonelada de líneas rectas pequeñas?). –

+0

@LarsTackmann, si SVG tuviera el pedido 4 de Béziers, esperaría poder dibujar polinomios cuárticos, y así sucesivamente. Pero eso se volvería complejo rápidamente. El uso de splines Bézier (debería ser capaz de hacer coincidir las derivadas primera y segunda) se vería mejor que los segmentos de línea, pero de cualquier manera, no sería exacto. – ephemient

Cuestiones relacionadas