Checking the Boundaries of an Ellipse in C#
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 C#
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 a new class;
Call it EllipticalRegion.
Type out the adjoining C# 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.
Dymetric class
using System.Windows.Forms;
namespace Dymetric
{
class Dymetric
{
private EllipticalRegion ellipse_zone;
private bool do_simulation;
public Dymetric(int screen_width, int screen_height)
{
ellipse_zone = new EllipticalRegion(screen_width, screen_height);
do_simulation = false;
}
public void decideAction(PaintEventArgs e, bool click_check)
{
if (do_simulation && click_check)
{
ellipse_zone.inPlay(e);
do_simulation = false;
}
else
{
ellipse_zone.clearAndDraw(e);
do_simulation = true;
}
}
}
}
C# code for EllipticalRegion class
using System;
using System.Threading;
using System.Drawing;
using System.Windows.Forms;
namespace Dymetric
{
class EllipticalRegion
{
private int x_square, y_square, previous_x, previous_y;
private const int squareLENGTH = 80;
private int h, k, a, b;
private const int dotDIAMETER = 10;
private Bitmap offscreen_bitmap;
Graphics offscreen_g;
private Brush bg_colour;
private Pen square_pen;
public EllipticalRegion(int screen_width, int screen_height)
{
square_pen = new Pen(Color.Yellow);
square_pen.Width = 5;
bg_colour = new SolidBrush(Color.LightGray);
offscreen_bitmap = new Bitmap(screen_width, screen_height - 55,
System.Drawing.Imaging.PixelFormat.Format24bppRgb);
offscreen_g = Graphics.FromImage(offscreen_bitmap);
offscreen_g.Clear(Color.LightGray);
previous_x = x_square = 10;
previous_y = y_square = offscreen_bitmap.Height / 2 - squareLENGTH / 2;
h = offscreen_bitmap.Width / 2;
k = offscreen_bitmap.Height / 2;
a = offscreen_bitmap.Width / 3;
b = offscreen_bitmap.Height / 3;
}
public void clearAndDraw(PaintEventArgs e)
{
offscreen_g.DrawEllipse(Pens.Black, h - a, k - b, 2 * a, 2 * b);
offscreen_g.FillRectangle(bg_colour, previous_x - 5, previous_y - 5, squareLENGTH + 10, squareLENGTH + 10);
offscreen_g.DrawRectangle(square_pen, x_square, y_square, squareLENGTH, squareLENGTH);
previous_x = x_square;
previous_y = y_square;
Graphics gr = e.Graphics;
gr.DrawImage(offscreen_bitmap, 0, 55, offscreen_bitmap.Width, offscreen_bitmap.Height);
}
public void inPlay(PaintEventArgs e)
{
while (x_square < offscreen_bitmap.Width - squareLENGTH)
{
int square_left = x_square;
int square_right = x_square + squareLENGTH;
int square_top = y_square;
int square_bottom = y_square + squareLENGTH;
int x_left_det = (int)Math.Round(((double)b / a)
* Math.Sqrt(Math.Pow(a, 2) - Math.Pow((square_left - h), 2)));
int x_right_det = (int)Math.Round(((double)b / a)
* Math.Sqrt(Math.Pow(a, 2) - Math.Pow((square_right - h), 2)));
int y_up_det = (int)Math.Round(((double)a / b)
* Math.Sqrt(Math.Pow(b, 2) - Math.Pow((square_top - k), 2)));
int y_down_det = (int)Math.Round(((double)a / b)
* Math.Sqrt(Math.Pow(b, 2) - Math.Pow((square_bottom - k), 2)));
square_pen.Dispose();
square_pen = new Pen(Color.Yellow);
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)
{
square_pen = new Pen(Color.Green);
}
square_pen.Width = 5;
clearAndDraw(e);
x_square += 10;
Thread.Sleep(50);
}
x_square = 10;
y_square = offscreen_bitmap.Height / 2 - squareLENGTH / 2;
}
}
}