Checking the Boundaries of a Quadratic Curve in C#
Remember that any quadratic equation always have two roots for any
value of y (except at it's maximum or minimum point).
All we need to do is use these two roots (x values) as boundaries
for our check.
y = ax2 + bx + c
ax2 + bx + (c-y) = 0
x = |
-b ± √(b2 - 4a(c-y)) |
2a |
Our range will then be:
-b - √(b2 - 4a(c-y)) |
≤ x ≤ |
-b + √(b2 - 4a(c-y)) |
2a |
2a |
where a, b, and c
are constants.
We will reuse the moving ball graphic and check for when
it enters the region of our curve.
Code to Detect Entrance into Quadratic Region in C#
To check for when our ball enters the quadratic curve,
we will continually check the x position
of the ball against the x position gotten using the
quadratic equation at the same y position
as that of the ball.
We'll designate the coordinates of the ball as
(xb, yb), and those of
the curve as (xq, yq).
Create a class;
Call it and QuadraticRegion.
Type out the adjoining C# code for detecting the instance a travelling
body crosses the boundary of a quadratic curve.
Dymetric class
using System.Windows.Forms;
namespace Dymetric
{
class Dymetric
{
private QuadraticRegion quad_region;
private bool do_simulation;
public Dymetric(int screen_width, int screen_height)
{
quad_region = new QuadraticRegion(screen_width, screen_height);
do_simulation = false;
}
public void decideAction(PaintEventArgs e, bool click_check)
{
if (do_simulation && click_check)
{
quad_region.inPlay(e);
do_simulation = false;
}
else
{
quad_region.clearAndDraw(e);
do_simulation = true;
}
}
}
}
C# code for QuadraticRegion class
using System;
using System.Threading;
using System.Drawing;
using System.Windows.Forms;
namespace Dymetric
{
class QuadraticRegion
{
private int x_ball, y_ball, previous_x, previous_y;
private const int ballDIAMETER = 80;
private int xq_start, yq_start, xq_min, yq_min, xq_stop, x, y;
private double xq_lb, xq_ub;
private double a, b, c, discriminant;
private const int dotDIAMETER = 5;
private Bitmap offscreen_bitmap;
Graphics offscreen_g;
private Brush ball_colour, dot_colour, bg_colour;
public QuadraticRegion(int screen_width, int screen_height)
{
ball_colour = new SolidBrush(Color.Yellow);
dot_colour = new SolidBrush(Color.Black);
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_ball = 10;
previous_y = y_ball = offscreen_bitmap.Height / 2 - ballDIAMETER / 2;
xq_start = offscreen_bitmap.Width / 2 - 200;
yq_start = 10;
xq_min = offscreen_bitmap.Width / 2;
yq_min = offscreen_bitmap.Height - 70;
xq_stop = offscreen_bitmap.Width / 2 + 200;
a = (yq_start - yq_min) / Math.Pow((xq_start - xq_min), 2);
b = -2 * a * xq_min;
c = yq_min + a*Math.Pow(xq_min, 2);
discriminant = Math.Sqrt(b*b - 4*a*(c - (y_ball - ballDIAMETER / 2)));
if (a < 0)
{
xq_lb = (-b + discriminant) / (2 * a);
xq_ub = (-b - discriminant) / (2 * a);
}
else
{
xq_lb = (-b - discriminant) / (2 * a);
xq_ub = (-b + discriminant) / (2 * a);
}
}
public void clearAndDraw(PaintEventArgs e)
{
for (x = xq_start; x <= xq_stop; x++)
{
y = (int)Math.Round(a * x * x + b * x + c);
offscreen_g.FillEllipse(dot_colour, x, y, dotDIAMETER, dotDIAMETER);
}
offscreen_g.FillEllipse(bg_colour, previous_x, previous_y, ballDIAMETER, ballDIAMETER);
offscreen_g.FillEllipse(ball_colour, x_ball, y_ball, ballDIAMETER, ballDIAMETER);
previous_x = x_ball;
previous_y = y_ball;
Graphics gr = e.Graphics;
gr.DrawImage(offscreen_bitmap, 0, 55, offscreen_bitmap.Width, offscreen_bitmap.Height);
}
public void inPlay(PaintEventArgs e)
{
while (x_ball < offscreen_bitmap.Width - ballDIAMETER)
{
ball_colour = new SolidBrush(Color.Yellow);
if ((x_ball <= xq_lb && x_ball + ballDIAMETER >= xq_lb)
|| (x_ball <= xq_ub && x_ball + ballDIAMETER >= xq_ub))
{
ball_colour = new SolidBrush(Color.Red);
}
else if (x_ball >= xq_lb && x_ball + ballDIAMETER <= xq_ub)
{
ball_colour = new SolidBrush(System.Drawing.Color.Green);
}
clearAndDraw(e);
x_ball += 5;
Thread.Sleep(50);
}
x_ball = 10;
y_ball = offscreen_bitmap.Height / 2 - ballDIAMETER / 2;
}
}
}