JavaScript и тригонометрия / овал - PullRequest
1 голос
/ 16 мая 2011

Я использовал эту овальную функцию (которую я нашел в Википедии http://en.wikipedia.org/wiki/Ellipse) для построения точек в макете. Я без проблем выкладывал две-пять точек вокруг овала.Функция имеет параметр 'steps'; параметр 'steps' устанавливает количество точек, которые нужно построить вокруг овала.

Вот основная проблема: If 'steps' (количество точек для построения графика).) равно числам 7, 11, 13 или 14, оно ломается . Прошло несколько лет с тех пор, как я взял тригонометрию, поэтому я застрял.

Второй незначительный вопрос: у меня был кодраспечатывая все точки, но когда я скопировал / вставил и удалил посторонний код для публикации здесь, он печатает только последнюю точку печати (не уверен почему).

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

Ответы [ 2 ]

1 голос
/ 16 мая 2011

Я бы объявил elipticalLayout внутри функции и вернул бы ее.Ниже описано, как написать функцию.

Обратите внимание, что в javascript нет такого понятия, как "двойное" или даже целое число, тип переменной определяется ее значением.Числа - это просто числа, они могут быть примитивами или объектами Number (почти никогда не требуются).

Если вы используете возвращенные значения для построения позиций в пикселях, вы, скорее всего, хотите сначала округлить их до целых чисел.Я использовал простой метод усечения, чтобы преобразовать их в целые числа.

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;
  }
}
0 голосов
/ 16 мая 2011

Вы заполняете только steps количество элементов в elipticalLayout. Но пытаюсь вывести 36 из них.

Это elipticalLayout[i/(360/steps)][0]=X; неверно, поскольку приведет к «дырам» в последовательности из-за округления от float до int.

У вас должно быть что-то вроде этого:

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