Frage

Zuerst nur eine visuelle Vorstellung davon zu geben, was ich nach, hier ist das nächste Ergebnis (noch nicht genau, was ich nach) Bild, das ich gefunden habe:

eingeben Bild Beschreibung hier

Hier ist die gesamte Website-Referenz: http://www.mathematische-basteleien.de/ spiral.htm

ABER, ist es nicht genau das Problem zu lösen, ich bin nach. Ich möchte eine Reihe von Punkten einer sehr spezifischen Spirale Algorithmus speichern.

  • Die Punkte werden gleichmäßig verteilt
  • Die 360-Grad-Zyklen haben einen gleichmäßigen Spalt

Wenn ich mich nicht irre, die ersten beiden Punkte wären:

  • Punkt [0] = new Point (0,0);
  • Punkt [1] = new Point (1,0);

Aber wo man von hier geht?

Die einzigen Argumente Ich mag würde zu schaffen, sind:

  • die Menge der Punkte, die ich zu lösen wollen (Länge des Array).
  • der Abstand zwischen den einzelnen Punkten (Pixel gap).
  • der Abstand zwischen den Zyklen.

Es ist fast Klänge, zu mir, dass ich das berechnen haben „ spiralUmfang “ (wenn es solch ein Begriff), um die gleichmäßig verteilten Punkten entlang der Spirale zu zeichnen.

2 * PI * Radius zuverlässig für diese Berechnung verwendet werden, denken Sie?

Wenn es vorher getan worden ist, finden Sie einige Codebeispiele zeigen!

War es hilfreich?

Lösung

Spaß kleines Problem:)

Wenn Sie auf das Diagramm näher betrachten, wird die Sequenz klar gesagt:

Spiral-Diagramm

Es gibt wahrscheinlich viele Lösungen zeichnen diese, vielleicht elegantere, aber hier ist meins:

Sie wissen, dass die Hypotenuse ist Quadratwurzel der aktuellen Segmentanzahl + 1 und die gegenüberliegende Seite des Dreiecks ist immer 1.

Auch wissen Sie, dass Sinus (Math.sin) des Winkels auf der gegenüberliegenden Seite durch die Hypotenuse geteilt gleich ist. von der alten mnenonic SOH (Sinus, Opposite, Hypotenuse.), - CAH-TOA

Math.sin(angle) = opp/hyp

Sie kennen den Wert des Sinus des Winkels, wissen Sie, die beiden Seiten, aber Sie wissen nicht, den Winkel noch, aber man kann den Arcussinus-Funktion (Math.asin) für das

verwenden
angle = Math.asin(opp/hyp)

Jetzt wissen Sie den Winkel für jedes Segment und Bekanntmachung erhöht er mit jeder Zeile.

Nun, da Sie einen Winkel haben und einen Radius (die Hypotenuse) Sie können für die Verwendung polar kartesischer Formel zu konvertieren, die Winkel, Radius Paar zu einem x, y Paar.

x = Math.cos(angle) * radius;
y = Math.sin(angle) * radius;

Da Sie für eine Actionscript-Lösung gefragt, da Point-Klasse bietet diese Funktion bereits für Sie durch die polar () Methode. Sie passieren sie einen Radius und Winkel und es gibt Ihre x und y in einem Point-Objekt.

Hier ist ein kleiner Ausschnitt, die die Spirale aufgetragen ist. Sie können die Anzahl der Segmente steuern, indem Sie mit der Maus auf der Y-Achse bewegt wird.

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;
}

Das haben könnte bereits in weniger Zeilen geschrieben, aber ich wollte diese in zwei Funktionen aufgeteilt: eine, die sich nur mit den Zahlen Berechnung, und die andere, die sich mit den Linien zu ziehen.

Hier sind einige Screenshots:

Spirale 1

Spirale 2

Spirale 3

Für Spaß habe ich eine Version dieser mit ProcessingJS hier . Führt ein bisschen langsam, so würde ich Chrom / Chrom für diese empfehlen.

Jetzt können Sie tatsächlich diesen Code ausführen hier (die Maus nach oben und unten):

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>

Andere Tipps

George Antwort war ausgezeichnet! Ich war für die Lösung für eine ganze Weile suchen.

Hier ist der gleiche Code für PHP eingestellt, falls es jemand hilft. Ich verwende den Skript Punkte zu zeichnen (= Städte) für eine Karte mit X, Y-Koordinaten. X von links beginnt, Y beginnt von unten links.

<?
/**
 * Initialize variables
 **/

// MAXIMUM width & height of canvas (X: 0->400, Y: 0->400)
$width = 400;

// For loop iteration amount, adjust this manually
$segments = 10000;

// Scale for radius
$radiusScale = 2;

// Draw dot (e.g. a city in a game) for every N'th drawn point
$cityForEveryNthDot = 14; 

/**
 * Private variables
 **/
$radius = 0;
$angle = 0;
$centerPoint = $width/2;

/**
 * Container print
 **/
print("<div style=\"width: ${width}px; height: ${width}px; background: #cdcdcd; z-index: 1; position: absolute; left: 0; top: 0;\"></div>");

/**
 * Looper
 **/
for($i=0;$i<$segments;$i++) {
    // calculate radius and angle
    $radius = sqrt($i+1) * $radiusScale;
    $angle += asin(1/$radius);

    // skip this point, if city won't be created here
    if($i % $cityForEveryNthDot != 0) {
        continue;
    }   

    // calculate X & Y (from top left) for this point
    $x = cos($angle) * $radius;
    $y = sin($angle) * $radius;

    // print dot
    print("<div style=\"width: 1px; height: 1px; background: black; position: absolute; z-index: 2; left: " . round($x+$centerPoint) . "; top: " . round($y+$centerPoint) . ";\"></div>");

    // calculate rounded X & Y (from bottom left)
    $xNew = round($x+$centerPoint);
    $yNew = round($width - ($y+$centerPoint));

    // just some internal checks
    if($xNew > 1 && $yNew > 1 && $xNew < $width && $yNew < $width) {
        /**
         * do something (e.g. store to database). Use xNew and yNew
         **/
    }   
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top