Como parte de una app de iOS que estoy haciendo, quiero dibujar una aproximación decente de una espiral de Arquímedes. La biblioteca de dibujo que estoy usando (CGPath en Quartz 2D, que está basada en C) admite arcos, así como curvas de Bézier cúbicas y cuadráticas. ¿Cuál es un buen método para aproximar una espiral de Arquímedes utilizando cualquiera de estos tipos de trazos? Por ejemplo, la imagen ejemplo de Wikipedia dice que fue "dibujada como una serie de segmentos de Bézier de mínimo error." ¿Cómo se generarían tales segmentos?
Mi formación matemática me lleva hasta Cálculo III además de algunas cosas que aprendí en una clase de mecánica clásica, pero han pasado un par de años, así que estoy oxidado. Lo que tengo hasta ahora:
Para una espiral r = a + b $\theta$, utilicé la información de esta página para encontrar que la pendiente cartesiana en cualquier punto (r, $\theta$) es igual a
$$\frac{dy}{dx}=\frac{b\sin\theta\space+\space(a + b\theta)\cos\theta}{b\cos\theta\space-\space(a + b\theta)\sin\theta}$$
A partir de aquí, podría utilizar la pendiente de punto para encontrar la ecuación de una línea tangente en cualquier punto, pero ¿cómo puedo encontrar las longitudes adecuadas de las asas (es decir, las posiciones de los dos puntos intermedios) para la curva? ¿O sería mejor/más fácil/más rápido una aproximación con segmentos de arco circulares?
Si no puedo resolverlo, simplemente usaré una imagen estática en la app, ¡pero se me ocurre que ni siquiera conozco una forma de generar una imagen de alta calidad de una espiral de Arquímedes! La herramienta de Espiral en Illustrator, por ejemplo, solo hace espirales logarítmicas.
0 votos
Su biblioteca de dibujo no puede evaluar funciones trigonométricas?
0 votos
¿Quieres decir sin/cos/tan? Estoy usando C, asi que sí, puedo. ¿A donde quieres llegar?
1 votos
Entonces, ¿por qué no simplemente usar las ecuaciones paramétricas reales de la espiral de Arquímedes en lugar de intentar dibujar una aproximación de Bézier?
1 votos
@J.M. La mayoría de las bibliotecas de dibujo fuera de software matemático especializado solo permiten dibujar primitivas como segmentos de línea, elipses y curvas cúbicas de Bézier, pero no curvas paramétricas arbitrarias. Espero que Zev pueda evaluar funciones trigonométricas para seleccionar los parámetros de estas primitivas, pero no puede hacer que la curva siga un camino paramétrico arbitrario.
0 votos
Correcto estás @RahulNarain. ¡Ojalá pudiera hacer eso!
1 votos
Este comentario no responde a la pregunta tal como está formulada, pero si fuera tú, @Zev, solo evaluaría posiciones a lo largo de la curva en pequeños incrementos de $\theta$ y las conectaría con una serie de segmentos de línea.
0 votos
Sabes, ni siquiera se me ocurrió ver si podía hacer que se viera suave usando segmentos de línea recta. Ahora que tengo información de la respuesta a continuación, quiero intentarlo, pero también probaré esta versión.
1 votos
Dibujar muchos segmentos de línea recta es una mala idea; en muchas bibliotecas gráficas puede causar errores de representación (por ejemplo, debido a la superposición de alisado o problemas de redondeo). No lo sufre tanto Quartz, pero en Quartz el rendimiento será terrible porque, para evitar el problema del alisado, necesita calcular auto intersecciones.
0 votos
Solo para añadir a mi comentario anterior, si necesitas descomponer en segmentos de línea, es mejor subdividir de forma adaptativa hasta que la curva pueda ser aproximada por una línea recta. Esto minimiza los problemas de renderizado.
0 votos
Por si te sirve de algo, esa página a la que haces referencia muestra fórmulas para dx/dy y dy/dx (es decir, cuánto cambian x e y, respectivamente, al cambiar ). Puedes obtener tus puntos de control multiplicando dx/d e dy/d por algún ángulo, y esos serán tus desplazamientos de x e y para tus puntos de control de la curva de Bézier cúbica. Otra opción es simplemente tomar una serie de puntos de la espiral y luego representarla usando algún algoritmo de suavizado, como la spline de Hermite. De nuevo, muy sencillo y logra una espiral con buen aspecto.