Jump to content
  • Advertisement
Sign in to follow this  
AcidZombie24

solved: checking if an x,y point is within an ellipse

This topic is 3694 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am trying to do 2 things, draw an ellipse and check if an x,y coord is within that ellipse I found a site with some sample code. I modified it and this is what i got. It seems to work well
#define nSeg 360
#define pi 3.14

void MyDrawEllipse(char *buf, u32 width, u32 height, u32 pitch, s2d_ptRect *ptR)
{
    double x, y, _x, _y, __x, __y, dx, dy, z, wx, hy;
    z = 0.99; //Point coordinate affinity

	dx = double(ptR->right)		/ 2.0 - 1.0; //Half window height
    dy = double(ptR->bottom)	/ 2.0 - 1.0; //Half window width
    wx = double(ptR->right)		/ 2.0; //Ellipse center
    hy = double(ptR->bottom)	/ 2.0; //Ellipse center

    for(int i = 0; i < int(nSeg); i++) {
        x = wx * sin((double(i) / double(nSeg)) * (pi*2.0));
        y = hy * cos((double(i) / double(nSeg)) * (pi*2.0));
        if(i > 0) {
            //Draw a line connecting the last point to the one being calculated now

			setPixel(buf, width, height, pitch, -1, int(dx+_x+z), int(dy+-_y+z));
			//setPixel(buf, width, height, pitch, -1, int(dx+x+z), int(dy+-y+z));
			//setPixel(buf, width, height, pitch, -1, X, Y);
            //g.DrawLine(&p, int(dx+_x+z), int(dy+-_y+z), int(dx+x+z), int(dy+-y+z));
        } else {
            //Save the first point coordinate to link it with the last one
            __x = x;
            __y = y;
			//setPixel(buf, width, height, pitch, -1, __x, __y);
        }
        //Save the actual point coordinate to link it with the next one

        _x = x;
        _y = y;
    }
//    g.DrawLine(&p, int(dx+x+z), int(dy+-y+z), int(dx+__x+z), int(dy+-__y+z));
	setPixel(buf, width, height, pitch, -1, int(dx+x+z), int(dy+-y+z));
	setPixel(buf, width, height, pitch, -1, int(dx+__x+z), int(dy+-__y+z));
	//setPixel(buf, width, height, pitch, -1, X, Y);
}





now with that same code modified it to check if an x,y point is within the ellipse. I figured an easy way to do it is get the angle between the center of the ellipse and the xy point i want to check. Plug that angle into the formula to get the farthest x,y and check if the target xy is within range.
bool isInEllipse(s2d_ptRect *ptR, int x2, int y2)
{
    double x, y, _x, _y, __x, __y, dx, dy, z, wx, hy;
    z = 0.99; //Point coordinate affinity

	dx = double(ptR->right)		/ 2.0 - 1.0; //Half window height
    dy = double(ptR->bottom)	/ 2.0 - 1.0; //Half window width
    wx = double(ptR->right)		/ 2.0; //Ellipse center
    hy = double(ptR->bottom)	/ 2.0; //Ellipse center

	int x1=wx, y1 = hy;
	//get angle between center and target x,y
	double angle = atan2((float)y2 - y1, x2 - x1) * 180 / PI;
/*
	x = wx * sin((double(angle) / double(nSeg)) * (pi*2.0));
	y = hy * cos((double(angle) / double(nSeg)) * (pi*2.0));
*/
	x = wx * sin((angle));
	y = hy * cos((angle));
	bool b = abs(wx - x2) <=abs(x);
	b = b && abs(hy - y2) <=abs(y);
	return b;
}






I had a feeling i did something wrong so i decided to test it like so
			int x, y;
			for (x=0; x<p->s->dim.width;  x++) {
			for (y=0; y<p->s->dim.height; y++) {
				if (isInEllipse(&r, x, y))
					setPixel(buf, p->s->dim.width, p->s->dim.height, p->s->dim.pitch, -1, x, y);
			}
			}





With that test, i discover it is wrong. But i have no idea how to fix it. The images it produce was. It might as well be broken, i need a better algorithm anyways. I have no idea how to fix this and spent hours on this problem already :( [Edited by - AcidZombie24 on July 9, 2008 1:36:21 AM]

Share this post


Link to post
Share on other sites
Advertisement
An ellipse is a scaled circle (basically, it's been scaled along its long axis by an amount equal to the ratio between the long and the short radius). Therefore, if you scale the entire world (the ellipse and the point) by the inverse of that amount along that same axis, you will end up with a point-circle text that's much easier to do.

Share this post


Link to post
Share on other sites
Rotaerk helped me on irc by giving me a nice formula.


bool isInEllipse(s2d_ptRect *ptR, int x2, int y2)
{
float ex, ey, eWidth, eHeight;

eWidth = double(ptR->right - ptR->left) / 2.0;
eHeight = double(ptR->bottom - ptR->top ) / 2.0;

ex = eWidth + ptR->left;
ey = eHeight+ ptR->top;

//(x - h)^2 * b^2 + (y - k)^2 * a^2 <= a^2 * b^2
//(x - ex)^2 * b^2 + (y - ey)^2 * a^2 <= a^2 * b^2
//(x - ex)^2 * eWidth^2 + (y - ey)^2 * eWidth^2 <= eWidth^2 * eWidth^2

return pow((x2 - ex),2) * pow(eHeight, 2) + pow((y2 - ey),2) * pow(eWidth, 2) <= pow(eWidth, 2) * pow(eHeight, 2);
}


-Edit-
I pasted a more correct version.

[Edited by - AcidZombie24 on July 9, 2008 6:35:48 PM]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!