[12503] | 1 | using System;
|
---|
| 2 | using System.Collections.Generic;
|
---|
| 3 | using System.Linq;
|
---|
| 4 | using System.Text;
|
---|
| 5 | using System.Windows;
|
---|
| 6 | using System.Windows.Media.Media3D;
|
---|
| 7 |
|
---|
| 8 | namespace Microsoft.Research.DynamicDataDisplay.Common.Auxiliary
|
---|
| 9 | {
|
---|
| 10 | public static class TriangleMath
|
---|
| 11 | {
|
---|
| 12 | public static bool TriangleContains(Point a, Point b, Point c, Point m)
|
---|
| 13 | {
|
---|
| 14 | double a0 = a.X - c.X;
|
---|
| 15 | double a1 = b.X - c.X;
|
---|
| 16 | double a2 = a.Y - c.Y;
|
---|
| 17 | double a3 = b.Y - c.Y;
|
---|
| 18 |
|
---|
| 19 | if (AreClose(a0 * a3, a1 * a2))
|
---|
| 20 | {
|
---|
| 21 | // determinant is too close to zero => apexes are on one line
|
---|
| 22 | Vector ab = a - b;
|
---|
| 23 | Vector ac = a - c;
|
---|
| 24 | Vector bc = b - c;
|
---|
| 25 | Vector ax = a - m;
|
---|
| 26 | Vector bx = b - m;
|
---|
| 27 | bool res = AreClose(ab.X * ax.Y, ab.Y * ax.X) && !AreClose(ab.LengthSquared, 0) ||
|
---|
| 28 | AreClose(ac.X * ax.Y, ac.Y * ax.X) && !AreClose(ac.LengthSquared, 0) ||
|
---|
| 29 | AreClose(bc.X * bx.Y, bc.Y * bx.X) && !AreClose(bc.LengthSquared, 0);
|
---|
| 30 | return res;
|
---|
| 31 | }
|
---|
| 32 | else
|
---|
| 33 | {
|
---|
| 34 | double b1 = m.X - c.X;
|
---|
| 35 | double b2 = m.Y - c.Y;
|
---|
| 36 |
|
---|
| 37 | // alpha, beta and gamma - are baricentric coordinates of v
|
---|
| 38 | // in triangle with apexes a, b and c
|
---|
| 39 | double beta = (b2 / a2 * a0 - b1) / (a3 / a2 * a0 - a1);
|
---|
| 40 | double alpha = (b1 - a1 * beta) / a0;
|
---|
| 41 | double gamma = 1 - beta - alpha;
|
---|
| 42 | return alpha >= 0 && beta >= 0 && gamma >= 0;
|
---|
| 43 | }
|
---|
| 44 | }
|
---|
| 45 |
|
---|
| 46 | private const double eps = 0.00001;
|
---|
| 47 | private static bool AreClose(double x, double y)
|
---|
| 48 | {
|
---|
| 49 | return Math.Abs(x - y) < eps;
|
---|
| 50 | }
|
---|
| 51 |
|
---|
| 52 | public static Vector3D GetBaricentricCoordinates(Point a, Point b, Point c, Point m)
|
---|
| 53 | {
|
---|
| 54 | double Sac = GetSquare(a, c, m);
|
---|
| 55 | double Sbc = GetSquare(b, c, m);
|
---|
| 56 | double Sab = GetSquare(a, b, m);
|
---|
| 57 |
|
---|
| 58 | double sum = (Sab + Sac + Sbc) / 3;
|
---|
| 59 |
|
---|
| 60 | return new Vector3D(Sbc / sum, Sac / sum, Sab / sum);
|
---|
| 61 | }
|
---|
| 62 |
|
---|
| 63 | public static double GetSquare(Point a, Point b, Point c)
|
---|
| 64 | {
|
---|
| 65 | double ab = (a - b).Length;
|
---|
| 66 | double ac = (a - c).Length;
|
---|
| 67 | double bc = (b - c).Length;
|
---|
| 68 |
|
---|
| 69 | double p = 0.5 * (ab + ac + bc); // half of perimeter
|
---|
| 70 | return Math.Sqrt(p * (p - ab) * (p - ac) * (p - bc));
|
---|
| 71 | }
|
---|
| 72 | }
|
---|
| 73 | }
|
---|