Пример #1
0
        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);
        }
Пример #2
0
        public static void GetBarycentricCoords(Coords2D _xyA, Coords2D _xyB, Coords2D _xyC, Coords2D _xy,
                                                out double a, out double b, out double c)
        {
            a = double.NaN;
            b = double.NaN;
            c = double.NaN;
            if (!Coords2D.IsInsideTriangle(_xyA, _xyB, _xyC, _xy, true))
            {
                return;
            }

            // solving the eq system:
            // _xy.X = a * _xyA.X + b * _xyB.X + (1 - a - b) * _xyC.X
            // _xy.Y = a * _xyA.Y + b * _xyB.Y + (1 - a - b) * _xyC.Y
            double denominator = (_xyB.Y - _xyC.Y) * (_xyA.X - _xyC.X) + (_xyC.X - _xyB.X) * (_xyA.Y - _xyC.Y);

            if (Math.Abs(denominator) < Calculation.MIN_DOUBLE_VAL)
            {
                return;
            }

            a = ((_xyB.Y - _xyC.Y) * (_xy.X - _xyC.X) + (_xyC.X - _xyB.X) * (_xy.Y - _xyC.Y)) / denominator;
            b = ((_xy.Y - _xyC.Y) * (_xyA.X - _xyC.X) + (_xyC.X - _xy.X) * (_xyA.Y - _xyC.Y)) / denominator;
            c = 1 - a - b;
        }
Пример #3
0
        private static Dictionary <Coords2D, double> Lists2Func2D(List <double> _xs, List <double> _ys, List <double> _zs)
        {
            if (_xs == null || _ys == null || _zs == null)
            {
                return(null);
            }

            int n = _xs.Count;

            if (n < 1 || n != _ys.Count || n != _zs.Count)
            {
                return(new Dictionary <Coords2D, double>());
            }

            Dictionary <Coords2D, double> Fxy = new Dictionary <Coords2D, double>();

            for (int i = 0; i < n; i++)
            {
                Coords2D xy = new Coords2D(_xs[i], _ys[i]);
                if (Fxy.ContainsKey(xy))
                {
                    continue;
                }
                Fxy.Add(xy, _zs[i]);
            }
            return(Fxy);
        }
Пример #4
0
        public static bool InGeneralPosition(Coords2D _xy1, Coords2D _xy2)
        {
            if (_xy1 == null || _xy2 == null)
            {
                return(false);
            }

            double diffX = _xy1.X - _xy2.X;
            double diffY = _xy1.Y - _xy2.Y;

            return(Math.Abs(diffX) >= Calculation.MIN_DOUBLE_VAL || Math.Abs(diffY) >= Calculation.MIN_DOUBLE_VAL);
        }
Пример #5
0
 public static bool InGeneralPosition(Coords2D _xy1, Coords2D _xy2, Coords2D _xy3)
 {
     return(Coords2D.InGeneralPosition(_xy1, _xy2) &&
            Coords2D.InGeneralPosition(_xy2, _xy3) &&
            Coords2D.InGeneralPosition(_xy3, _xy1));
 }
Пример #6
0
        public static double Interpolate2D(Coords2D _xy, List <Coords2D> _XYs, List <double> _Zs)
        {
            Dictionary <Coords2D, double> Fxy = Lists2Func2D(_XYs, _Zs);

            return(Interpolate2D(_xy, Fxy));
        }
Пример #7
0
        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]);
        }