Silverlight mathematical engine (8)-intersection point of ruler plotting 2

Source: Internet
Author: User
Tags silverlight

The most embarrassing weather in the year has arrived in Shenzhen, where the quilt is hot, cold, and the umbrella does not rain. If it does not rain, it may become a zombie, and even mosquitoes that are invisible in the summer, this season has also turned out to be a blessing, so I can't help but recall the four-Season climate in my hometown...

We will continue to study the next intersection. Because the intersection of the line and the circle is relatively simple, we will only discuss the intersection of the circle and the circle. In fact, it is not difficult, that is, too many algebra is too cumbersome, you just need to clarify it step by step. Look at the equation of the circle:

(X-A) 2-(Y-B) 2 = R2

(A, B) is the center of the circle, and r is the radius, which is intuitive. Calculating the intersection of two circles is to solve such a equations. First, we define a circle according to this formula:

// Circle: (x-A) 2 + (Y-B) 2 = R2 public class logicalcircle {public logicalcircle (logicalpoint center, logicalline radius) {center = center; radius = radius;} public logicalpoint center {Get; set;} public logicalline radius {Get; set;} public double A {get {return center. X ;}} public Double B {get {return center. Y ;}} public double r {get {return radius. length ;}}}

To solve a binary quadratic equation, we first convert it into a quadratic equation:

Ax2 + bx + c = 0

Although I have been away from junior high school for a long time, everyone must have been familiar with this thing. In the sea of questions tactics of that year, almost every time there is its shadow, especially its root-seeking formula:

As for how the root-seeking formula came from, I was too lazy to think about it. The teacher told us to stick it down like this, so we don't have to worry about solving the problem.

To calculate the intersection of two circles, we should not first convert the equations into a quadratic equation (of course there are other methods) to see how the code is implemented:

// Circle :( X-A) 2 + (Y-B) 2 = R2 // circle :( X-A) 2 + (Y-B) 2 = R2 public static tuple <logicalpoint, logicalpoint> circleandcircle (logicalcircle circle1, logicalcircle circle2) {var p1 = new logicalpoint (double. positiveinfinity, double. positiveinfinity); var P2 = new logicalpoint (double. positiveinfinity, double. positiveinfinity); If (circle1.r + circle2.r)-circle1.center. distance (circle2.center) <0) {// two circles are separated, no point of intersection} e LSE {// returns the first binary equation of X and Y by subtraction between the left and right: Y = mx + N; var M = (circle1.a-circle2.a)/(circle2. B-circle1. B ); vaR n = (circle1.r. sqr ()-circle2.r. sqr () + circle2.a. sqr ()-circle1.a. sqr () + circle2. B. sqr ()-circle1. B. sqr ()/(2*(circle2. B-circle1. B); // y = mx + N is substituted into the equation of circle: (x-A) 2 + (mx + N-B) 2 = R2 // the standard formula for converting to a quadratic equation: ax2 + bx2 + c = 0 var q = N-circle1. B; var A = m. sqr () + 1; var B = 2 * (M * q-circle1.a); var c = circle1.a. sqr () + Q. sqr ()-circle1.r. sqr (); // obtain the two roots of the equation ax2 + bx + c = 0 var d = B * B-4 * a * C; if (A = 0 & B! = 0) p1.x =-C/B; If (D = 0) p1.x =-B/(2 * A); else if (D> 0) {d = D. squareroot (); p1.x = (-B-d)/(2 * A); p2.x = (-B + d)/(2 * );} // input X to the linear equation to obtain Y: p1.y = m * p1.x + N; p2.y = m * p2.x + N; If (p1.distance (P2 ). iszero () {p2.x = double. positiveinfinity; // The two intersections overlap, indicating that P2 does not exist} return New tuple <logicalpoint, logicalpoint> (P1, P2 );}

In the code, we handle two special cases: the separation of two circles and the tangent. Separation directly sets the intersection point to non-existent. For the tangent, the two intersections actually overlap. It is OK if we don't handle it, because on the screen, the overlapping display also looks like a point, but why does P2 not exist? The reason is that if we add names such as A and B to the vertex and display them on the screen, when the two points are repeated, A and B also overlap, which is hard to see, so we choose to remove one, in addition, don't give it up!

There is another problem here. Since there are two intersections, which one should I take if I only need one of them? Don't you understand? Let's take a look. When the two circles are handed over to E and F, will the coordinate of E be P1 or P2 in the upper solution? After tests, we find that, if we connect A, E, B, and f clockwise, e is always P1 and F is P2. This provides a theoretical basis for the subsequent mouse cross-point operations, so that when the mouse is clicked at point F, it will not let the cross point go to point E.

In addition, the straight line also has a circular problem. Assume that the line AB and the circle have two intersections E and F, where E corresponds to P1, F corresponds to P2, the direction of EF is the same as that of AB,

OK. After the analysis is complete, we will improve our testing program below:

  1. Use the elements we tested earlier (Free Point P1, P2, free line P1P2)
  2. Create two new free points (PO1, PO2)
  3. PO1, PO2 as the center, P1P2 as the radius of two circles
  4. Create two intersections of P1P2 and PO1
  5. Create two intersections of PO1 and PO2
  6. Add mouse events so that free points can be dragged.

After everything is ready, the two circles also come out, but the center of the circle cannot be dragged. After debugging, our hittest method has a problem:

        public static T HitTest<T>(this Panel panel, Point p) where T : FrameworkElement        {            var t = VisualTreeHelper.FindElementsInHostCoordinates(p, panel).FirstOrDefault();            if (t != null && t is T)                return (T)t;            return null;        }

This method does not return free points as expected, but returns a circle (because vertices and circles are both ellipse). Why? Because the circle is created later, it is located at the top layer, hittest returns only one ellipse, which is of course the top layer. The solution is to specify different zindexes in the pointshape and circleshape Constructor (ensure that the circle is OK below the vertex), as follows:

        public PointShape(LogicalPoint center)        {            Center = center;            Shape = new Ellipse { Width = Size, Height = Size, Fill = Brushes.Green, Stroke = Brushes.Black };            Shape.Tag = this;            Canvas.SetZIndex(Shape, 100);        }

Get it done, run it. Let's see how to run it:

 

[Source code and demo address]

Next we will introduce the online and circle points. The new dawn is coming!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.