Reputation: 3036
I have been using this this oval function (that I found at Wikipedia http://en.wikipedia.org/wiki/Ellipse) for plotting points in a layout. I have been laying things out with two to five points plotted around an oval without any problem. The function has a parameter called 'steps'; the 'steps' parameter sets the quantity of points to plot around the oval.
Here's the main problem: If 'steps' (the number of points to plot) is equal to the numbers 7, 11, 13 or 14, it breaks. It's been a few years since I took trigonometry, so basically I am stuck.
Second minor issue: I had the code printing out all points, but when I copied/pasted and removed extraneous code to post here, it only prints out the last plotting point (not sure why).
<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>
Upvotes: 1
Views: 872
Reputation: 147523
I would declare elipticalLayout
within the function and return it. Below is how I'd write the function.
Note that there is no such thing as a "double" or even integer in javascript, a variable's type is defined by its value. Numbers are just numbers, they can be primitives or Number objects (almost never required).
If you are using the returned values to plot positions in pixels, you likely want to round them to integers first. I've used a simple truncation method to convert them to integers.
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;
}
}
Upvotes: 1
Reputation: 27470
You fill only steps
number of elements in elipticalLayout.
But trying to output 36 of them.
This elipticalLayout[i/(360/steps)][0]=X;
is wrong as will lead to "holes" in the sequence due to float
to int
rounding.
You should have something like this:
var n = 0;
for(...)
elipticalLayout[n][0]=X;
elipticalLayout[n][1]=Y;
++n;
Upvotes: 0