Checking the Boundaries of an Ellipse in JavaScript
From the equation
(x - h)2 |
+ |
(y - k)2 |
= 1 |
a2 |
b2 |
It can be deduced that
y = k ± b/a√(a2 - (x - h)2)
;
And conversely
x = h ± a/b√(b2 - (y - k)2)
Hence, the boundaries of any circle lie in the range
y ≥ k - b/a√(a2 - (xexternal - h)2);
y ≤ k + b/a√(a2 - (xexternal - h)2)
and
x ≥ h - a/b√(b2 - (yexternal - k)2);
x ≤ h + a/b√(b2 - (yexternal - k)2)
Code to Detect Entrance into an Elliptical Region in JavaScript
To check for when a second graphic enters the ellipse,
we will continually use the x position
of this second graphic in the ellipse equation to detect
when its y position lies between the up and down
limits at the x position in question:
y2nd_img(top) >
k - b/a√(a2 - (x2nd_img - h)2)
and y2nd_img(bottom) <
k + b/a√(a2 - (x2nd_img - h)2)
;
At the same time, we will use the y position
of the second graphic in the circle equation to detect
when its x position lies between the left and
right limits at the y position in question:
x2nd_img(left) >
h - a/b√(b2 - (y2nd_img - k)2)
and x2nd_img(right) <
h + a/b√(b2 - (y2nd_img - k)2)
Create 2 new files; On Notepad++: File, New.
Call them elliptical_region.html and elliptical_region.js.
Type out the adjoining JavaScript code for detecting the instance a travelling
body crosses the boundary of an ellipse.
By The Way: Notice how the equations for a circle
are similar to those of an ellipse;
No surprise there!
A circle is just an ellipse in its simplest form.
elliptical_region.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Elliptical Region</title>
</head>
<body>
<h3>Detect a Second Body entering an Ellipse</h3>
<canvas id="ellipse_region" width="600" height="450" style="border: 1px solid #000000;">
Your browser (version) does not support canvas object; Time to update!
</canvas>
<button onclick="ellipsedSquare()">Glide</button>
<button onclick="clearTimeout(clr_obj)">Stop</button>
<script src="EllipticalRegion.js"></script>
</body>
</html>
JavaScript code for elliptical_region.js
var canvas = document.getElementById("ellipse_region");
var context = canvas.getContext("2d");
context.fillStyle = "#888888";
var x_square = 10;
var y_square = 250;
var sq_length = 100;
context.fillRect(x_square, y_square, sq_length, sq_length);
var h = 350;
var k = 225;
var a = 200;
var b = 150;
var x = h - a;
var y = k;
for (; x < h + a; x++) {
y = k - (b / a) * Math.sqrt(Math.pow(a, 2) - Math.pow((x - h), 2));
context.beginPath();
context.arc(x, y, 1, 0, 2 * Math.PI);
context.fill();
y = k + (b / a) * Math.sqrt(Math.pow(a, 2) - Math.pow((x - h), 2));
context.beginPath();
context.arc(x, y, 1, 0, 2 * Math.PI);
context.fill();
}
function ellipsedSquare() {
if (x_square + sq_length < 600) {
context.clearRect(x_square - 10, y_square, sq_length, sq_length);
var square_left = x_square;
var square_right = x_square + sq_length;
var square_top = y_square;
var square_bottom = y_square + sq_length;
var x_left_det = (b / a) * Math.sqrt(Math.pow(a, 2) - Math.pow((square_left - h), 2));
var x_right_det = (b / a) * Math.sqrt(Math.pow(a, 2) - Math.pow((square_right - h), 2));
var y_up_det = (a / b) * Math.sqrt(Math.pow(b, 2) - Math.pow((square_top - k), 2));
var y_down_det = (a / b) * Math.sqrt(Math.pow(b, 2) - Math.pow((square_bottom - k), 2));
if (square_top > k - x_left_det && square_bottom < k + x_left_det &&
square_top > k - x_right_det && square_bottom < k + x_right_det &&
square_left > h - y_up_det && square_right < h + y_up_det &&
square_left > h - y_down_det && square_right < h + y_down_det) {
context.fillStyle = "#00ff00";
} else {
context.fillStyle = "#888888";
}
context.fillRect(x_square, y_square, sq_length, sq_length);
x_square += 10;
clr_obj = setTimeout(function () {
ellipsedSquare();
}, 100);
}
}