pequeño problema diversión :)
Si nos fijamos en el diagrama más cerca, la secuencia se afirma claramente:
Probablemente hay muchas soluciones a dibujar estos, tal vez más elegante, pero aquí está el mío:
Usted sabe que la hipotenusa es la raíz cuadrada del conteo del segmento actual + 1 y el lado opuesto del triángulo es siempre 1.
También sabes que Sine (Math.sin) del ángulo es igual al lado opuesto dividido por la hipotenusa. del antiguo SOHN sennen (Sine, Opuesto, Hipotenusa), - CAH-TOA.
Math.sin(angle) = opp/hyp
conoce el valor del seno del ángulo, se conocen los dos lados, pero no saben el ángulo todavía, pero se puede utilizar el arco función seno (Math.asin) para que
angle = Math.asin(opp/hyp)
Ahora conoce el ángulo de cada segmento y observe que se incrementa con cada línea.
Ahora que tiene un ángulo y un radio (la hipotenusa) se puede utilizar para polar a cartesiano fórmula para convertir que ángulo, radio par a una x, y par.
x = Math.cos(angle) * radius;
y = Math.sin(angle) * radius;
Has solicitado que una solución ActionScript, hay clase Point ya proporciona esta función para usted a través del método polar(). Le pasa un radio y un ángulo y devuelve su xey en un objeto Point.
Aquí hay un pequeño fragmento que traza la espiral. Puede controlar la cantidad de segmentos moviendo el mouse en el eje Y.
var sw:Number = stage.stageWidth,sh:Number = stage.stageHeight;
this.addEventListener(Event.ENTER_FRAME,update);
function update(event:Event):void{
drawTheodorus(144*(mouseY/sh),sw*.5,sh*.5,20);
}
//draw points
function drawTheodorus(segments:int,x:Number,y:Number,scale:Number):void{
graphics.clear();
var points:Array = getTheodorus(segments,scale);
for(var i:int = 0 ; i < segments; i++){
points[i].offset(x,y);
graphics.lineStyle(1,0x990000,1.05-(.05+i/segments));
graphics.moveTo(x,y);//move to centre
graphics.lineTo(points[i].x,points[i].y);//draw hypotenuse
graphics.lineStyle(1+(i*(i/segments)*.05),0,(.05+i/segments));
if(i > 0) graphics.lineTo(points[i-1].x,points[i-1].y);//draw opposite
}
}
//calculate points
function getTheodorus(segments:int = 1,scale:Number = 10):Array{
var result = [];
var radius:Number = 0;
var angle:Number = 0;
for(var i:int = 0 ; i < segments ; i++){
radius = Math.sqrt(i+1);
angle += Math.asin(1/radius);//sin(angle) = opposite/hypothenuse => used asin to get angle
result[i] = Point.polar(radius*scale,angle);//same as new Point(Math.cos(angle)*radius.scale,Math.sin(angle)*radius.scale)
}
return result;
}
esto podría haber sido escrito en menos líneas, pero quería dividirla en dos funciones: uno que sólo se ocupa de calcular los números, y el otro que se ocupa de la elaboración de las líneas.
Estas son algunas capturas de pantalla:
Para la diversión que añade una versión de esto utilizando ProcessingJS here. Se ejecuta un poco lento, por lo que recomendaría Chromium/Chrome para esto.
ahora hasta puede ejecutar este código aquí (mover el ratón hacia arriba y hacia abajo): Respuesta
var totalSegments = 850,hw = 320,hh = 240,segments;
var len = 10;
points = [];
function setup(){
createCanvas(640,480);
smooth();
colorMode(HSB,255,100,100);
stroke(0);
noFill();
//println("move cursor vertically");
}
function draw(){
background(0);
translate(hw,hh);
segments = floor(totalSegments*(mouseY/height));
points = getTheodorus(segments,len);
for(var i = 0 ; i < segments ; i++){
strokeWeight(1);
stroke(255-((i/segments) * 255),100,100,260-((i/segments) * 255));
line(0,0,points[i].x,points[i].y);
// strokeWeight(1+(i*(i/segments)*.01));
strokeWeight(2);
stroke(0,0,100,(20+i/segments));
if(i > 0) line(points[i].x,points[i].y,points[i-1].x,points[i-1].y);
}
}
function getTheodorus(segments,len){
var result = [];
var radius = 0;
var angle = 0;
for(var i = 0 ; i < segments ; i++){
radius = sqrt(i+1);
angle += asin(1/radius);
result[i] = new p5.Vector(cos(angle) * radius*len,sin(angle) * radius*len);
}
return result;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.4.4/p5.min.js"></script>
Por "Cada punto se distribuye uniformemente", ¿quiere decir "El ángulo entre puntos consecutivos es una constante", o algo más? – mbeckish
Esta pregunta es probablemente una mejor coincidencia para math.stackexchange.com. –
Por "Cada ciclo de 360 grados tiene un espacio par", ¿quiere decir "La diferencia entre el radio en el ángulo xy el radio en el ángulo x + 2 * Pi es una constante", o algo más? – mbeckish