예제 #1
0
        /// <returns>typeof Direction</returns>
        public int GetFromAndFillType(Direction to, Basin3 toBasin, HealpixManager man)
        {
            if (Ring == toBasin.Ring)
            {
                Type = to;
            }

            var vert = NeighborManager.GetVert(to);

            if (Ring == 1 && vert == NeighborVert.North ||
                Ring == man.RingsCount && vert == NeighborVert.South ||
                Type == to)
            {
                return((int)NeighborManager.GetOppositeHor(to));
            }
            return((int)NeighborManager.GetOpposite(to));
        }
예제 #2
0
        protected override void CalcDeltasH()
        {
            foreach (var basin in PixMan.Pixels)
            {
                if (basin.HasWater()
                    //   && basin.P==62
                    )
                {
                    // -.5Pi .. 1.5Pi
                    var alphas = new double[4];
                    // Pi .. .5Pi
                    var gammas      = new double[4];
                    var lengths     = new double[4];
                    var normLengths = new double[4];
                    foreach (Direction to in Enum.GetValues(typeof(Direction)))
                    {
                        var toBasin     = basin.Neibors[to];
                        var deltaBeta   = (basin.Beta - toBasin.Beta).Value;
                        var deltaLambda = (basin.Lambda - toBasin.Lambda).Value
                                          * basin.BetaSin
                        ;     //*2;

                        var length = Math.Sqrt(deltaBeta * deltaBeta + deltaLambda * deltaLambda);
                        lengths[(int)to] = length;

                        //var asin = Math.Asin(deltaBeta / length);
                        //alphas[(int) to] = deltaLambda > 0 ? asin : Math.PI - asin;
                        gammas[(int)to] = Math.Atan(Math.Abs(deltaBeta / deltaLambda));
                    }

                    /*foreach (int to in Enum.GetValues(typeof(Direction)))
                     * {
                     *  lengths[to] = lengths.Max() - lengths[to];
                     * }*/
                    foreach (int to in Enum.GetValues(typeof(Direction)))
                    {
                        normLengths[to] = lengths[to] / lengths.Sum();
                    }

                    //todo exclude second calculaton of the same pair, set and look on basin.Volumes
                    foreach (Direction to in Enum.GetValues(typeof(Direction)))
                    {
                        var    toBasin = basin.Neibors[to];
                        double HtoVer;

                        var hor    = NeighborManager.GetHor(to);
                        var HtoHor = basin.Hto[2 + hor] - toBasin.Hto[2 + 1 - hor];
                        //(basin.hOQ - toBasin.hOQ) //not r because of bottom relief  * 1; //hack
                        if (Math.Abs(HtoHor) > 10)
                        {
                        }

                        var vert = NeighborManager.GetVert(to);
                        if (basin.Ring == 1 && vert == NeighborVert.North ||
                            basin.Ring == HealpixManager.RingsCount && vert == NeighborVert.South ||
                            basin.Type == to)
                        {
                            basin.froms[(int)to] = (int)NeighborManager.GetOppositeHor(to);
                            HtoVer = 0;
                        }
                        else
                        {
                            var from = NeighborManager.GetOpposite(to);
                            basin.froms[(int)to] = (int)from;
                            HtoVer = basin.Hto[(int)vert] -
                                     toBasin.Hto[1 - (int)vert];

                            //if (basin.Type == from && HtoVer < 0) HtoVer = -HtoVer * .5;//hack
                        }

                        var deltaHfull = Math.Sin(gammas[(int)to]) * HtoVer + Math.Cos(gammas[(int)to]) * HtoHor;
                        basin.deltasH[(int)to] = deltaHfull * normLengths[(int)to];
                        if (Math.Abs(basin.deltasH[(int)to]) > 100 ||
                            basin.P == 17)
                        {
                        }
                    }
                }
            }
        }
예제 #3
0
        public BasinDataDotProduct(HealpixManager man, bool withRelief = false, bool spheric = false,
                                   double?min = null, double?max = null)
            : base(man, null, min, max)
        {
            _withRelief  = withRelief;
            _spheric     = spheric;
            ColorsMiddle = 0;

            foreach (var basin in PixMan.Pixels)
            {
                RecalcDelta_g(basin);

                // 0 .. almost Pi/2
                //Gammas = new double[4];

                var alphas = new double[4];

                var bisectors = new Point3D[4];
                var lengths   = new double[4];
                //!var surface = basin.Surface;
                var xyPlane = new Plane(basin.Q3, new UnitVector3D(0, 0, basin.Vartheta > 0 ? 1 : -1));
                //!var xAxis = xyPlane.IntersectionWith(surface);
                foreach (Direction to in Enum.GetValues(typeof(Direction)))
                {
                    var toBasin = PixMan.Pixels[man.Neibors.Get(to, basin)];
                    basin.Neibors[to] = toBasin;

                    basin.froms[(int)to] = basin.GetFromAndFillType(to, toBasin, HealpixManager);

                    basin.MeanEdges[(int)to] = man.Neibors.MeanBoundary(basin, to);

                    basin.InitialHto[(int)to] = basin.Metric(toBasin, (int)to);

                    //!var otherQprojection = toBasin.Q3.ProjectOn(surface);//TraverseCalm);
                    //var dx = toBasin.Qb.X * Math.Sin(basin.Lambda.Value - toBasin.Lambda.Value);
                    //var dy = new Line3D(toBasin.Q3, otherQprojection).Length;
                    //lengths[(int)to] = Math.Sqrt(dx * dx + dy * dy);
                    //basin.Gammas[(int)to] = Math.Asin(dy / lengths[(int)to]);

                    /*!var Q_otherProjection = new Line3D(basin.Q3, otherQprojection);
                     * lengths[(int) to] = Q_otherProjection.Length;
                     *
                     * var thirdPoint = new Ray3D(basin.Q3, surface.Normal).LineTo(toBasin.Q3).StartPoint;
                     * var anglePlane = new Plane(basin.Q3, thirdPoint, toBasin.Q3);
                     * var lineQ3s = new Line3D(basin.Q3, toBasin.Q3);
                     * bisectors[(int) to] = Point3D.MidPoint(toBasin.Q3, thirdPoint);*/

                    //var xAxis = surface.Normal.Rotate(new UnitVector3D(0, 0, 1), 90, AngleUnit.Degrees);

                    //!alphas[(int) to] = xAxis.Direction.SignedAngleTo(Q_otherProjection.Direction, surface.Normal).Radians;

                    /*телесный угол, calc Cos by DotProduct
                     * alphas[(int)to] = surface.Normal.SignedAngleTo(lineQ3s.Direction,
                     *  anglePlane.Normal//surface.Normal.Orthogonal
                     *  ).Radians;//*/
                }
                foreach (Direction to in Enum.GetValues(typeof(Direction)))
                {
                    basin.NormLengths[(int)to] = lengths[(int)to] / lengths.Sum();
                    var deltaAngle = (alphas[(int)to] - alphas[(int)NeighborManager.GetOpposite(to)]);
                    var koef       = Math.Cos(1 * (Math.Abs(deltaAngle) - Math.PI));
                    //koef = Math.Sin(.5 * (alphas[(int)to] - alphas[(int)NeighborManager.GetOpposite(to)]));
                    //koef = Math.Sin(1 * (alphas[(int)to]));
                    //koef = Math.Tan(alphas[(int)to] - Math.PI/2);
                    basin.Koef[(int)to] = Math.Abs(Math.Pow(koef, 1));
                }
                // !basin.SpecNormal = new Line3D(basin.Q3, Point3D.Centroid(bisectors).MirrorAbout(surface)).Direction;

                if (_withRelief)
                {
                    int waterHeight;
                    var hOQ = GetHeights(basin, (int)basin.rOfEllipse, out waterHeight);
                    basin.hOQ = hOQ;
                    if (waterHeight > 0)
                    {
                        basin.Depth = waterHeight - hOQ;
                    }
                    else
                    {
                        basin.Depth = -hOQ;
                    }
                }
            }

            foreach (var basin in PixMan.Pixels)
            {
                foreach (Direction to in Enum.GetValues(typeof(Direction)))
                {
                    var toBasin = (BasinDotProduct)basin.Neibors[to];
                    basin.Koef2[(int)to] = basin.Koef[(int)to] * toBasin.Koef[(int)NeighborManager.GetOpposite(to)];
                }
            }
        }