2011-05-16 3 views
1

J'ai utilisé cette fonction ovale (que j'ai trouvé sur Wikipedia http://en.wikipedia.org/wiki/Ellipse) pour tracer des points dans une mise en page. J'ai posé des choses avec deux à cinq points tracés autour d'un ovale sans aucun problème. La fonction a un paramètre appelé 'steps'; le paramètre 'steps' définit la quantité de points à tracer autour de l'ovale.JavaScript et trigonométrie/ovale

Voici le problème principal: Si 'steps' (le nombre de points à tracer) est égal aux numéros 7, 11, 13 ou 14, il se casse. Cela fait quelques années que j'ai pratiqué la trigonométrie, donc je suis coincé.

Deuxième problème mineur: J'ai fait imprimer le code sur tous les points, mais lorsque j'ai copié/collé et enlevé du code étranger à poster ici, il imprime seulement le dernier point de tracé (je ne sais pas pourquoi).

<html> 
<head> 
<script type="text/javascript"> 
    var elipticalLayout=new Array(); 
    for (i=0; i <36; i++){ 
     elipticalLayout[i]=new Array(2); 
    } 

    /* 
    * This functions returns an array containing the specified 
    * number of 'steps' (points) to draw an ellipse. 
    * 
    * @param x {double} X coordinate 
    * @param y {double} Y coordinate 
    * @param a {double} Semimajor axis 
    * @param b {double} Semiminor axis 
    * @param angle {double} Angle of the ellipse 
    * 
    * Attribution: This function is from http://en.wikipedia.org/wiki/Ellipse 
    */ 
    function calculateEllipticalLayout(x, y, a, b, angle, steps) { 

     var points = []; 

     // Angle is given by Degree Value 
     var beta = -angle * (Math.PI/180); //(Math.PI/180) converts Degree Value into Radians 
     var sinbeta = Math.sin(beta); 
     var cosbeta = Math.cos(beta); 

     for (var i = 0; i < 360; i += 360/steps) //{ 
     var alpha = i * (Math.PI/180) ; 
     var sinalpha = Math.sin(alpha); 
     var cosalpha = Math.cos(alpha); 

     var X = x + (a * cosalpha * cosbeta - b * sinalpha * sinbeta); 
     var Y = y + (a * cosalpha * sinbeta + b * sinalpha * cosbeta); 
     elipticalLayout[i/(360/steps)][0]=X; 
     elipticalLayout[i/(360/steps)][1]=Y; 
    } 

    </script> 
</head> 
<body> 
    <script type="text/javascript"> 

     calculateEllipticalLayout(300, 300, 245, 125, 15, 15); 

     for (i=0; i<elipticalLayout.length; i++){ 
      document.write(i + ", " + elipticalLayout[i][0] + ", " + elipticalLayout[i][1] + "<br>"); 
     } 
    </script> 

</body> 
</html> 

Répondre

0

Vous ne remplir que steps nombre d'éléments dans elipticalLayout. Mais essayant de sortir 36 d'entre eux.

Cette erreur elipticalLayout[i/(360/steps)][0]=X; est erronée car elle entraînera des "trous" dans la séquence en raison de float à int arrondi.

Vous devriez avoir quelque chose comme ceci:

var n = 0; 
for(...) 
    elipticalLayout[n][0]=X; 
    elipticalLayout[n][1]=Y; 
    ++n; 
+0

Je vais réfléchir à cela; Merci. En ce qui concerne le tableau, le tableau est utilisé à plusieurs reprises pour disposer différents ovales avec différentes quantités de points. J'ai suivi le nombre de pas (points), donc le fait que le tableau soit plus grand que le nombre de points réels n'a pas été un problème (bien que je réalise que ce n'est pas une solution élégante, je ne crois pas la taille du tableau est un problème). –

+0

Cela l'a corrigé. Je vous remercie. –

1

je déclarerais elipticalLayout dans la fonction et le retourner. Voici comment j'écrirais la fonction.

Notez qu'il n'existe pas de "double" ou même d'entier en javascript, le type d'une variable est défini par sa valeur. Les nombres sont juste des nombres, ils peuvent être des objets primitifs ou des nombres (presque jamais requis).

Si vous utilisez les valeurs renvoyées pour tracer des positions en pixels, vous souhaiterez probablement les arrondir d'abord aux entiers. J'ai utilisé une méthode de troncature simple pour les convertir en entiers.

var elipticalLayout = []; 

/* 
* This functions returns an array containing the specified 
* number of 'steps' (points) to draw an ellipse. 
* 
* @param x  - X coordinate 
* @param y  - Y coordinate 
* @param a  - Semimajor axis 
* @param b  - Semiminor axis 
* @param angle - Angle of the ellipse 
* 
* Attribution: This function is from http://en.wikipedia.org/wiki/Ellipse 
*/ 
function calculateEllipticalLayout(x, y, a, b, angle, steps) { 

    var points = []; 
    var step = 360/steps; 
    var k = Math.PI/180; // Convert deg to rad 
    var cos = Math.cos; 
    var sin = Math.sin; 
    var i = 0; 

    // Convert angle to radians 
    var beta = -angle * k; 
    var sinbeta = sin(beta); 
    var cosbeta = cos(beta); 

    while (i < 360) { 

    var alpha = i * k; 
    var sinalpha = sin(alpha); 
    var cosalpha = cos(alpha); 

    var X = x + (a * cosalpha * cosbeta - b * sinalpha * sinbeta); 
    var Y = y + (a * cosalpha * sinbeta + b * sinalpha * cosbeta); 

    // Truncate numbers to integer and put into array 
    elipticalLayout.push([X|0, Y|0]); 

    // Keep X,Y as floats 
    // elipticalLayout.push([X, Y]); 

    i += step; 
    } 
}