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

Recommended Posts

My problem wasn't resolved in my previous post so I m trying again:
public void drawCircle(SpriteBatch spriteBatch, Texture2D blank, Vector2 position, float radius)
{
float angle = 0;
for (int i = 1; i <= 360; i++)
{
position.X = position.X + (float)Math.Cos(angle);
position.Y = position.Y + (float)Math.Sin(angle);
spriteBatch.Draw(blank, position, null, Color.White, angle, new Vector2(blank.Width / 2f, blank.Height / 2f), 1f, SpriteEffects.None, 1f);
}
}


I want to draw a circle around a triangle(its circumcircle) my code above draws a wrongly sized circle even if I do position.X = position.X + radius* (float)Math.Cos(angle); First of all is my approach of drawing a circle correct? Is there a better way than drawing 360 points? Secondly to draw the circle around the triangle I have already calculated the radius and the positions of the three points of the triangle if that helps Thanks!

Share on other sites
The problem was resolved in your previous post, at least the problem that's evident in the code you have posted now. You can not update the same variable like that, as it will use the previous point as the center for the next point. Declare a new Vector2 position, which you set to position = center + radius * cos/sin each iteration. You pass center and radius to the function, and never change them. Only change the new local variable position which you use to draw at.

Share on other sites
ok thanks let me try it :P

Share on other sites

As far as drawing a circle around the triangle I could calculate the center point of the triangle and then determine the radius based on the 3 points which define the triangle. Draw your circle with that center point and your calculated radius.

Share on other sites
[source lang=c#]public void drawCircle(SpriteBatch spriteBatch, Texture2D blank, Vector2 position, Vector2 center, float radius)        {            float angle = 0;            for (int i = 1; i <= 360; i++)            {                position.X = center.X + radius  * (float)Math.Cos(angle);                position.Y = center.Y + radius  * (float)Math.Sin(angle);                spriteBatch.Draw(blank, position, null, Color.White, angle, new Vector2(blank.Width / 2f, blank.Height / 2f), 1f, SpriteEffects.None, 1f);                angle = angle + MathHelper.ToRadians(1f);            }         }

the radius is making the circle too big in this algorithm

@CornyKorn21 thats what I ve been trying to do, I dont know how put it in the algorithm so that the radius will make the circle appear correctly.

PS: I know that all my numbers are correct because I have a whole delaunay algorithm up and working, I just want to draw a circle :P

Share on other sites
You need to understand scope. You need a temporary Vector2 inside the scope of the for loop:

1) remove the position argument from your function

2)
for ( blah blah ){    Vector2 position;    position.X = center.X + blah blah;    position.Y = center.X + blah blah;    blah blah}

I don't know why you're passing both position and center into your function....

-me

Share on other sites
ok it makes more sense now I made a temporary vector2 but still the radius make the circle huge

Share on other sites
Also as for your triangle problem. The 3 points of the triangle are not guaranteed to fall on the circumference of any circle. The best you can hope for is a circle that encloses all the points with the furthest point lying on the circumference.

To find the necessary things:

Average the points of the triangle together, this will get you the center.
Do a distance calculation between each point and this center
The averaged center is the center of your circle

-me

Share on other sites
Remember also that radius and all your points are not in pixels. it's units of space. The settings for your viewport, projection matrix and model view matrix will determine how big a unit is on screen.

So describe what you mean exactly by "too big"

Share on other sites
To give some visual output of whats the current results:

as you can see from these two pictures delaunay works correctly therefore my data is correct. There must be something wrong with the circle drawing code...

Also if I go about this way the angle the circle is drawn is wrong like you can see in picture two...

[Edited by - Tipotas688 on March 6, 2010 5:28:05 AM]

Share on other sites
Maybe the circle is correct, but the drawing of your triangle isn't (or the calculation of the center and radius). Can you please show us all the relevant drawing and calculation code ?

Share on other sites
So, the mystery is almost solved. This being a part of a bigger project where the code was hidden to me I assumed that since delaunay triangulation worked the center and radius that was given to me worked as well and I didn't want to recalculate it.

The hidden code implemented the algorithm by Paul Bourke and for some reason they were returning the center and radius of a supercircle the algorithm was using.

So I created a method to calculate everything based on the three vertices of the triangle

[source lang=c#]public static Circle calcCircle(Triangle triangle)        {            float a = (triangle.point1.X + triangle.point2.X + triangle.point3.X) / 3;            float b = (triangle.point1.Y + triangle.point2.Y + triangle.point3.Y) / 3;            Circle c = new Circle();            c.center = new Vector2(a, b);            float length1 = (triangle.point1 - c.center).Length();            float length2 = (triangle.point2 - c.center).Length();            float length3 = (triangle.point3 - c.center).Length();            float max = length1;            if (max < length2)                max = length2;            if (max < length3)                max = length3;            c.radius = max;            return c;        }

The result is shown in the following picture, blue is the calculated center, but thats the circle that encloses all the vertices and I need the one that "touches" all of them

Share on other sites
I shouldn't be searching for the center of the circmcircle as the center of the triangle though.

The circumcircle should be touching all 3 vertices
like in this applet http://www.cs.cornell.edu/home/chew/Delaunay.html

I presume that the code the project is using to calculate the delaunay diagram is this:

[source lang=c#]private static bool InCircle(Geometry.Point p, Geometry.Point p1, Geometry.Point p2, Geometry.Point p3)		{			//Return TRUE if the point (xp,yp) lies inside the circumcircle			//made up by points (x1,y1) (x2,y2) (x3,y3)			//NOTE: A point on the edge is inside the circumcircle			if (System.Math.Abs(p1.Y - p2.Y) < double.Epsilon && System.Math.Abs(p2.Y - p3.Y) < double.Epsilon)			{				//INCIRCUM - F - Points are coincident !!				return false;			}			double m1, m2;			double mx1, mx2;			double my1, my2;			double xc, yc;									if (System.Math.Abs(p2.Y - p1.Y) < double.Epsilon)			{				m2 = -(p3.X - p2.X) / (p3.Y - p2.Y);				mx2 = (p2.X + p3.X) * 0.5;				my2 = (p2.Y + p3.Y) * 0.5;				//Calculate CircumCircle center (xc,yc)				xc = (p2.X + p1.X) * 0.5;				yc = m2 * (xc - mx2) + my2;			}			else if (System.Math.Abs(p3.Y - p2.Y) < double.Epsilon)			{				m1 = -(p2.X - p1.X) / (p2.Y - p1.Y);				mx1 = (p1.X + p2.X) * 0.5;				my1 = (p1.Y + p2.Y) * 0.5;				//Calculate CircumCircle center (xc,yc)				xc = (p3.X + p2.X) * 0.5;				yc = m1 * (xc - mx1) + my1;			}			else			{				m1 = -(p2.X - p1.X) / (p2.Y - p1.Y);				m2 = -(p3.X - p2.X) / (p3.Y - p2.Y);				mx1 = (p1.X + p2.X) * 0.5;				mx2 = (p2.X + p3.X) * 0.5;				my1 = (p1.Y + p2.Y) * 0.5;				my2 = (p2.Y + p3.Y) * 0.5;				//Calculate CircumCircle center (xc,yc)				xc = (m1 * mx1 - m2 * mx2 + my2 - my1) / (m1 - m2);				yc = m1 * (xc - mx1) + my1;			}			double dx = p2.X - xc;			double dy = p2.Y - yc;			double rsqr = dx * dx + dy * dy;			//double r = Math.Sqrt(rsqr); //Circumcircle radius			dx = p.X - xc;			dy = p.Y - yc;			double drsqr = dx * dx + dy * dy;			return (drsqr <= rsqr);		}

taken from http://local.wasp.uwa.edu.au/~pbourke/papers/triangulate/morten.html

Share on other sites
Oh cheers! I ll try that. I do think though that since delaunay works, it should be somewhere in the code... I ll recompute it by all means to have it working. Thanks :)

Share on other sites
Done it works now, and I found the error, they were dividing: 2 * (mb - ma) but instead it should be: (2 * (mb - ma)) Thanks people :)

Share on other sites
Quote:
 Original post by PalidineAlso as for your triangle problem. The 3 points of the triangle are not guaranteed to fall on the circumference of any circle. The best you can hope for is a circle that encloses all the points with the furthest point lying on the circumference.To find the necessary things:Average the points of the triangle together, this will get you the center.Do a distance calculation between each point and this centerThe furthest distance is the radius of your circleThe averaged center is the center of your circle-me

In fact EVERY triangle has a circumcircle. If you find it, all vertices of the triangle are guaranteed to fall on the circle.

Share on other sites
Quote:
 Original post by Tipotas688First of all is my approach of drawing a circle correct? Is there a better way than drawing 360 points?

One thing I'd like to point out is that you're mixing radians and degrees.
Math.Sin and Math.Cos take an argument in radians. So something like this should make the circle more coherent:
public void drawCircle(SpriteBatch spriteBatch, Texture2D blank, Vector2 center, float radius){    Vector2 position;    int angle;    for (angle = 0; angle &lt;= 359; angle++)    {        double rad = MathHelper.ToRadians(angle);        position.X = center.X + radius * (float)Math.Cos(rad);        position.Y = center.Y + radius * (float)Math.Sin(rad);        spriteBatch.Draw(blank, position, null, Color.White, 0f, new Vector2(blank.Width / 2f, blank.Height / 2f), 1f, SpriteEffects.None, 1f);    }}

The circle can look even better if you make the number of points depend on the radius, so the larger the radius, the more points are drawn.

Also, Tom is right.

Share on other sites
Yeah cheers about the radian comment, I was kinda going blindly at it, I really didn't even know if drawing 360 points was the right way to go :)

Edit: I did try the code above but the points were not so connected