2011-07-26 49 views
16

He buscado y no he encontrado nada realmente sobre cómo dibujar espirales en lienzo usando JavaScript.Dibujando una espiral en un lienzo HTML usando JavaScript

Pensé que podría ser posible hacerlo con la curva de bezier y si eso no funcionó usa lineTo(), pero eso parecía mucho más difícil.

Además, para hacer eso, supongo que tendría que usar la trigonometría y la representación gráfica con coordenadas polares, y ha pasado un tiempo desde que lo hice. Si ese es el caso, ¿podría señalarme en la dirección correcta en matemáticas?

+0

¿Qué tipo de espiral ?: http: // e n.wikipedia.org/wiki/Spiral –

+0

¿Tiene en mente un tipo particular de espiral? – Gabe

+0

Estaba pensando algo así como la espiral de Arquímedes. Preferiblemente podría ajustar algunos parámetros para obtener una gama de diferentes espirales. – qw3n

Respuesta

31

La espiral de Arquímedes se expresa como r=a+b(angle). Convierta eso en coordenada x, y, se expresará como x=(a+b*angle)*cos(angle), y=(a+b*angle)*sin(angle). A continuación, se puede poner en un ángulo de bucle y hacer algo como esto:

for (i=0; i< 720; i++) { 
    angle = 0.1 * i; 
    x=(1+angle)*Math.cos(angle); 
    y=(1+angle)*Math.sin(angle); 
    context.lineTo(x, y); 
} 

Nota lo anterior supone a = 1 y B = 1.

Aquí hay un enlace jsFiddle: http://jsfiddle.net/jingshaochen/xJc7M/

+2

Esto funcionó, excepto para obtener el sprial que necesita para configurar el incremento en algo como 'i + =. 1' tal como es, se ve como polígonos. – qw3n

+0

@ qw3n: ¡Absolutamente correcto! Editado! –

+1

Variación leve en este violín http://jsfiddle.net/pTymD/ con incremento de ángulo variable para la velocidad: 'var incr = angle? 1/(a ​​+ b * ángulo): 0.1; '. Esto evita sobremuestreo en ángulos bajos y submuestreo en altos al apuntar a longitudes de línea de 1px. –

1

hay una herramienta gratuita muy bien que le ayudará si usted tiene ilustrador ai2canvas

creará todas las curvas a javascript en etiqueta canvas HTML para usted!

(si es que busca archmedes espiral que primero tendrá que obtener de CorelDRAW y copiar que a ilustrador, ya que la herramienta espiral por defecto aumenta el ángulo con cada punto)

2

Este es una versión ligeramente modificada, javascript-ified de una espiral de Java que tomé prestada de here

Utiliza lineTo() y no es tan difícil.

<!DOCTYPE HTML> 
<html><body> 
<canvas id="myCanvas" width="300" height="300" style="border:1px solid #c3c3c3;"></canvas> 
<script type="text/javascript"> 
    var c=document.getElementById("myCanvas"); 
    var cxt=c.getContext("2d"); 
    var centerX = 150; 
    var centerY = 150; 
    cxt.moveTo(centerX, centerY); 

    var STEPS_PER_ROTATION = 60; 
    var increment = 2*Math.PI/STEPS_PER_ROTATION;  
    var theta = increment; 

    while(theta < 40*Math.PI) { 
     var newX = centerX + theta * Math.cos(theta); 
     var newY = centerY + theta * Math.sin(theta); 
     cxt.lineTo(newX, newY); 
     theta = theta + increment; 
    } 
    cxt.stroke(); 
</script></body></html> 
+0

buena respuesta, pero fue básicamente lo mismo que el otro. – qw3n

+0

oh yeh, uy. Inicialmente pensé que era solo código psuedo. – icchanobot

2

Aquí es una función que escribí para la elaboración Archimedean spirals:

CanvasRenderingContext2D.prototype.drawArchimedeanSpiral = 
    CanvasRenderingContext2D.prototype.drawArchimedeanSpiral || 
     function(centerX, centerY, stepCount, loopCount, 
       innerDistance, loopSpacing, rotation) 
     { 
      this.beginPath(); 

      var stepSize = 2 * Math.PI/stepCount, 
       endAngle = 2 * Math.PI * loopCount, 
       finished = false; 

      for (var angle = 0; !finished; angle += stepSize) { 
       // Ensure that the spiral finishes at the correct place, 
       // avoiding any drift introduced by cumulative errors from 
       // repeatedly adding floating point numbers. 
       if (angle > endAngle) { 
        angle = endAngle; 
        finished = true; 
       } 

       var scalar = innerDistance + loopSpacing * angle, 
        rotatedAngle = angle + rotation, 
        x = centerX + scalar * Math.cos(rotatedAngle), 
        y = centerY + scalar * Math.sin(rotatedAngle); 

       this.lineTo(x, y); 
      } 

      this.stroke(); 
     } 
1

esto es ejemplo del dibujo espiral utilizando la función a continuación:

spiral(ctx, { 
    start: {//starting point of spiral 
    x: 200, 
    y: 200 
    }, 
    angle: 30 * (Math.PI/180), //angle from starting point 
    direction: false, 
    radius: 100, //radius from starting point in direction of angle 
    number: 3 // number of circles 
}); 

espiral código de dibujo:

spiral = function(ctx,obj) { 
    var center, eAngle, increment, newX, newY, progress, sAngle, tempTheta, theta; 
    sAngle = Math.PI + obj.angle; 
    eAngle = sAngle + Math.PI * 2 * obj.number; 
    center = { 
    x: obj.start.x + Math.cos(obj.angle) * obj.radius, 
    y: obj.start.y + Math.sin(obj.angle) * obj.radius 
    }; 
    increment = 2 * Math.PI/60/*steps per rotation*/; 
    theta = sAngle; 
    ctx.beginPath(); 
    ctx.moveTo(center.x, center.y); 
    while (theta <= eAngle + increment) { 
    progress = (theta - sAngle)/(eAngle - sAngle); 
    tempTheta = obj.direction ? theta : -1 * (theta - 2 * obj.angle); 
    newX = obj.radius * Math.cos(tempTheta) * progress; 
    newY = obj.radius * Math.sin(tempTheta) * progress; 
    theta += increment; 
    ctx.lineTo(center.x + newX, center.y + newY); 
    } 
    ctx.stroke(); 
}; 
Cuestiones relacionadas