#javascript #math #trigonometry
#javascript #математика #тригонометрия
Вопрос:
Я использовал эту функцию this oval (которую я нашел в Википедии http://en.wikipedia.org/wiki/Ellipse ) для нанесения точек на макет. Я раскладывал вещи с помощью двух-пяти точек, нанесенных вокруг овала, без каких-либо проблем. Функция имеет параметр, называемый «шаги»; параметр «шаги» задает количество точек для построения вокруг овала.
Вот основная проблема: если «шаги» (количество точек для построения графика) равны числам 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>
Ответ №1:
Я бы объявил elipticalLayout
внутри функции и вернул ее. Ниже показано, как бы я написал функцию.
Обратите внимание, что в javascript нет такого понятия, как «double» или даже целое число, тип переменной определяется ее значением. Числа — это просто числа, они могут быть примитивами или числовыми объектами (почти никогда не требуются).
Если вы используете возвращаемые значения для отображения позиций в пикселях, вы, вероятно, захотите сначала округлить их до целых чисел. Я использовал простой метод усечения, чтобы преобразовать их в целые числа.
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;
}
}
Ответ №2:
Вы заполняете только steps
количество элементов в elipticalLayout. Но пытаюсь вывести 36 из них.
Это elipticalLayout[i/(360/steps)][0]=X;
неправильно, поскольку приведет к «дырам» в последовательности из-за float
int
округления.
У вас должно получиться что-то вроде этого:
var n = 0;
for(...)
elipticalLayout[n][0]=X;
elipticalLayout[n][1]=Y;
n;
Комментарии:
1. Я подумаю об этом; спасибо. Что касается массива, то массив используется снова и снова для построения разных овалов с разным количеством точек. Я отслеживал количество шагов (точек), поэтому тот факт, что массив больше, чем количество фактических точек, не был проблемой (хотя я понимаю, что это не элегантное решение, я не думаю, что размер массива является проблемой).