14. Circle selection

The hint said that the perpendicular bisectors of a chord of a circle pass through the circle's center. To apply that hint to this problem, find a perpendicular bisector for the segment connecting two of the points selected by the user. That bisector passes through the circle's center.

The following FindBisector helper method finds a perpendicular bisector for a segment:

// Find a bisector for the segment connecting the two points.
private void FindBisector(PointF p0, PointF p1,
out PointF b0, out PointF b1)
{
// Find the midpoint.
b0 = new PointF(
(p0.X + p1.X) / 2,
(p0.Y + p1.Y) / 2);

// Find the p0-p1 direction vector.
float dx = p1.X - p0.X;
float dy = p1.Y - p0.Y;

// Add <dy, -dx> to b0 to get b1.
b1 = new PointF(
b0.X + dy,
b0.Y - dx);
}

The method first averages the two points, p0 and p1, to find the point at the center of the segment. The bisector must pass through that point.

Next, the code finds the <dx, dy> direction vector that points in the direction of the original segment. The two vectors <dy, -dx> and <-dy, dx> are perpendicular to <dx, dy>, one pointing to the left and the other to the right. The code adds <dy, -dx> to the segment's center point to get a new point that lies along the perpendicular bisector.

The following FindCircle method uses the FindBisector helper method to find the circle that passes through three points:

// Return a RectangleF that defines a circle
// passing through the three points.
private RectangleF FindCircle(PointF p0, PointF p1, PointF p2)
{
// Find a bisector for p0-p1.
PointF b00, b01;
FindBisector(p0, p1, out b00, out b01);

// Find a bisector for p1-p2.
PointF b10, b11;
FindBisector(p1, p2, out b10, out b11);

// Find the bisectors' point of intersection.
bool linesAreParallel;
PointF center = IntersectLines(b00, b01, b10, b11,
out linesAreParallel);
if (linesAreParallel)
{
MessageBox.Show("The circle's points are colinear");
return new RectangleF(-1, -1, -1, -1);
}

// Return the circle.
float radius = Distance(center, p0);
return new RectangleF(
center.X - radius, center.Y - radius,
2 * radius, 2 * radius);
}

This method calls the FindBisector helper method to find the chord bisectors. It then calls IntersectLines to see where the bisectors intersect.

The two bisectors will be parallel if the user's three points are co-linear. In that case, there is no circle that includes all three points.

Next, the method uses the Distance helper method to find the distance between the center point and one of the user's points. (The Distance method simply calculates the distance between two points. It's straightforward so I won't show it here.) That distance gives the radius of the circle.

The method finishes by a RectangleF that defines the circle. (You could store the circle's center point and radius instead, but the program's Paint event handler uses a RectangleF to draw the circle, so it's convenient to represent the circle as RectangleF.)

The rest of the program is reasonably straightforward if you use the tools provided by the previous solutions. Download the CircleSelection example program to see additional details.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.151.61