public static bool IsInsideTriangle(Coords2D _xyA, Coords2D _xyB, Coords2D _xyC, Coords2D _xy, bool _check_triangle = false) { if (_check_triangle) { if (!Coords2D.InGeneralPosition(_xyA, _xyB, _xyC)) { return(false); } } if (_xyA == null || _xyB == null || _xyC == null) { return(false); } double diff_xA = _xy.X - _xyA.X; double diff_xB = _xy.X - _xyB.X; double diff_xC = _xy.X - _xyC.X; bool inside_x = (Math.Sign(diff_xA) != Math.Sign(diff_xB)) || (Math.Sign(diff_xA) != Math.Sign(diff_xC)); double diff_yA = _xy.Y - _xyA.Y; double diff_yB = _xy.Y - _xyB.Y; double diff_yC = _xy.Y - _xyC.Y; bool inside_y = (Math.Sign(diff_yA) != Math.Sign(diff_yB)) || (Math.Sign(diff_yA) != Math.Sign(diff_yC)); return(inside_x && inside_y); }
public static bool InGeneralPosition(Coords2D _xy1, Coords2D _xy2, Coords2D _xy3) { return(Coords2D.InGeneralPosition(_xy1, _xy2) && Coords2D.InGeneralPosition(_xy2, _xy3) && Coords2D.InGeneralPosition(_xy3, _xy1)); }
private static double Interpolate2D(Coords2D _xy, Dictionary <Coords2D, double> _Fxy) { if (_Fxy == null || _Fxy.Count < 3) { return(double.NaN); } // find closest xy values SortedList <double, Coords2D> distances = new SortedList <double, Coords2D>(); foreach (Coords2D xy_current in _Fxy.Keys) { double dist = Math.Abs(_xy.X - xy_current.X) + Math.Abs(_xy.Y - xy_current.Y); distances.Add(dist, xy_current); } // construct the smallest well-defined triangle containing _xy Coords2D xyA = distances.ElementAt(0).Value; Coords2D xyB = distances.ElementAt(1).Value; int i = 1; if (!Coords2D.InGeneralPosition(xyA, xyB)) { for (; i < distances.Count; i++) { xyB = distances.ElementAt(i).Value; if (Coords2D.InGeneralPosition(xyA, xyB)) { break; } } } if (!Coords2D.InGeneralPosition(xyA, xyB)) { return(double.NaN); } Coords2D xyC = null; for (int j = 1; j < distances.Count && j != i; j++) { xyC = distances.ElementAt(j).Value; if (Coords2D.InGeneralPosition(xyA, xyB, xyC) && Coords2D.IsInsideTriangle(xyA, xyB, xyC, _xy, false)) { break; } } if (!Coords2D.InGeneralPosition(xyA, xyB, xyC) || !Coords2D.IsInsideTriangle(xyA, xyB, xyC, _xy, false)) { return(double.NaN); } // perform actual interpolation double a, b, c; Coords2D.GetBarycentricCoords(xyA, xyB, xyC, _xy, out a, out b, out c); if (double.IsNaN(a) || double.IsNaN(b) || double.IsNaN(c)) { return(double.NaN); } return(a * _Fxy[xyA] + b * _Fxy[xyB] + c * _Fxy[xyC]); }