Antes que nada, recomendaría usar una buena biblioteca de gráficos, como raphael. Simplificará el proceso de usar javascript para realizar el dibujo.
Un método muy simple de suavizar es convertir todos los comandos de línea a comandos con una curva equivalente a comandos y calcular algunos puntos de control según los ángulos de cada segmento de línea. Por ejemplo,
<svg width="1000" height="1000" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<path d="
M250 150
L150 350
L350 350
L250 150
" />
</svg>
convierte
<svg width="1000" height="1000" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<path d="
M250 150
C250 150 150 350 150 350
C150 350 350 350 350 350
C350 350 250 150 250 150
" />
</svg>
Ambos deben dibujar un triángulo equilátero
El siguiente paso sería calcular la posición de los puntos de control. En general, querrás que los puntos de control a cada lado de una esquina suave caigan sobre una línea imaginaria que pasa por el vértice. En el caso del punto superior del triángulo equilátero, esta sería una línea horizontal. Después de algunas manipulaciones, se puede obtener algo como esto:
<svg width="1000" height="1000" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<path d="
M250 150
C230 150 140 333 150 350
C160 367 340 367 350 350
C360 333 270 150 250 150
" />
</svg>
La parte difícil es el cálculo de los puntos de control, pero que se convierte en no mucho más que un simple problema de trigonometría. Como mencioné anteriormente, el objetivo aquí es poner los dos puntos de control en una línea que biseca el vértice de la esquina. Por ejemplo, supongamos que tenemos dos segmentos de línea:
A. (0,0) to (3,2)
B. (0,0) to (1,-4)
the absolute angle of A is arctan(2/3) = 33.69 deg
the absolute angle of B is arctan(-4/1) = -75.96 deg
the bisection angle of AB is (33.69 + -75.96)/2 = -21.135
the tangent angle is AB is (-21.135 + 90) = 68.865
conociendo el ángulo tangente, podemos calcular el punto de control posiciona
smoothness = radius = r
tangent angle = T
Vertex X = Xv
Vertex Y = Yv
Control Point 1:
Xcp1 = cos(T)*r
Ycp1 = sin(T)*r
Control Point 2:
Xcp2 = cos(T)*(-r)
Ycp2 = sin(T)*(-r)
El último problema es donde poner cada punto de control en el curveTo real comando:
CX1 Y1 X2 Y2 X3 Y3
X3 y Y3 definen la ubicación del vértice. X1 Y1 y X2 Y2 definen los puntos de control. Puede pensar que X1 Y1 define el vector de cómo ingresar el vértice y X2 Y2 define el vector de cómo salir. Ahora que tiene los dos puntos de control que debe decidir sobre
CXcp1 Ycp1 Xcp2 Ycp2 0 0
o
CXcp2 Ycp2 Xcp1 Ycp1 0 0
esta es una decisión importante. Si los haces hacia atrás, la forma se verá como un bucle. En este punto, debe poder determinar cómo debe tomarse esta decisión ...
De nuevo, esta es una solución muy simple, pero tiende a verse bien para las rutas dibujadas a mano. Una solución mejor podría llevarlo un paso más allá y mover el punto de intersección hacia adentro hacia la sección cóncava de cada intersección de segmento de línea. Esto es un poco más desafiante
Intenta usar curvas http://www.w3.org/TR/SVG/paths.html#PathDataCurveCommands – Gerben