Beispiel #1
0
        public Shape Equidista(double Distancia)
        {
            //retorna la equidistancia
            Shape Res = new Shape();

            //eqidistancia con signo, así las islas equidistan en el sentido correcto

            if (this._Puntos.Count > 2)//salta por no ser viable la equidistancia
            {
                Segmento Sn  = new Segmento(this._Puntos.Last <Punto>(), this._Puntos.First <Punto>());
                Segmento Sn1 = new Segmento();

                for (int i = 0; i < this._Puntos.Count; i++)
                {
                    int j = i + 1;
                    if (j >= this._Puntos.Count)
                    {
                        j = 0;
                    }

                    Sn1 = new Segmento(this._Puntos[i], this._Puntos[j]);

                    Punto TempRes = new Punto();
                    if (Sn.Interseccion2D(Sn1, out TempRes))
                    {
                        Res.AddPunto(TempRes);
                    }

                    Sn = Sn1;
                }
            }

            return(Res);
        }
Beispiel #2
0
        public IList <Segmento> SegmentosInteriores(Segmento Rayo)
        {
            IList <Segmento> Res = new List <Segmento>();

            Res = _Exterior.SegmentosInteriores(Rayo, false);

            if (Res.Count > 0)                 //si no corta el exterior tampoco a las islas
            {
                foreach (Shape Isla in _Islas) //por cada isla compara con todos los segmentos
                {
                    for (int i = 0; i < Res.Count; i++)
                    {
                        IList <Segmento> ResIsla = new List <Segmento>();

                        ResIsla = Isla.SegmentosInteriores(Res[i], true);

                        //reemplaza el segmento interior por el nuevo si han producido intersecciones
                        if (ResIsla.Count > 0)
                        {
                            Res.RemoveAt(i);

                            for (int j = 0; j < ResIsla.Count; j++)
                            {
                                Res.Insert(i + j, ResIsla[i]);
                            }
                        }
                    }
                }
            }

            return(Res);
        }
Beispiel #3
0
        public IList <Segmento> SegmentosInteriores(Segmento Rayo)
        {
            IList <Segmento> Res = new List <Segmento>();

            foreach (Poligono P in _Poligonos)
            {
                IList <Segmento> TempRes = P.SegmentosInteriores(Rayo);
                foreach (Segmento s in TempRes)
                {
                    Res.Add(s);
                }
            }

            return(Res);
        }
Beispiel #4
0
        public IList <Segmento> SegmentosInteriores(Segmento Rayo, bool Invertido = false)
        {
            IList <Segmento> Res = new List <Segmento>();

            IList <Punto> TempCortes = new List <Punto>();
            Punto         pAnt       = this._Puntos.Last <Punto>();

            //añado el punto inicial y final si se encuentran dentro del polígono
            if (this.EsInterior(Rayo.Inicio))
            {
                TempCortes.Add(Rayo.Inicio);
            }
            if (this.EsInterior(Rayo.Final))
            {
                TempCortes.Add(Rayo.Final);
            }

            foreach (Punto p in this._Puntos)
            {
                Segmento s       = new Segmento(pAnt, p);
                Punto    TempPto = new Punto();
                //calcula el corte real con el borde
                if (s.Corta(Rayo, out TempPto))
                {
                    if (!TempCortes.Contains <Punto>(TempPto))
                    {
                        TempCortes.Add(TempPto);
                    }
                }

                pAnt = p;
            }

            //TODO: //ordeno en función de la distancia a Rayo.Inicio
            TempCortes = TempCortes.OrderBy <Punto, double>(p => p.Distancia(Rayo.Inicio)).ToList <Punto>();

            //con TempCortes voy generando segmentos por pares y evaluando si el punto medio se encuentra dentro o no del polígono
            for (int p = 1; p < TempCortes.Count; p++)
            {
                bool Añadir = false;
                if (this.EsInterior(new Punto((TempCortes[p].X + TempCortes[p - 1].X) / 2.0,
                                              (TempCortes[p].Y + TempCortes[p - 1].Y) / 2.0,
                                              (TempCortes[p].Z + TempCortes[p - 1].Z) / 2.0)))
                {
                    if (!Invertido)//lo añado
                    {
                        Añadir = true;
                    }
                }
                else
                {
                    if (Invertido)//lo añado
                    {
                        Añadir = true;
                    }
                }

                if (Añadir)
                {
                    Res.Add(new Segmento(TempCortes[p - 1], TempCortes[p]));
                }
            }

            return(Res);
        }
Beispiel #5
0
        public bool EsInterior(Punto Pto)
        {
            //variación del windingnumber solo teniendo en cuenta el cambio de cuadrante
            bool Res = false;

            if (this._Puntos.Count > 2)
            {
                int CuadranteAnterior = 0, CuadranteActual = 0, ConteoCuadrantes = 0;

                IList <Punto> _Borde_ = new List <Punto>();

                foreach (Punto p in this._Puntos)
                {
                    _Borde_.Add(p);
                }

                _Borde_.Add(this._Puntos[0]);//repite contra el primero

                Punto pAnt = new Punto();
                foreach (Punto p in _Borde_)
                {
                    CuadranteActual = _Cuadrante(Pto, p);
                    if (CuadranteAnterior == 0)
                    {
                        //evita que el primer cálculo cuente como salto de cuadrante;
                        CuadranteAnterior = CuadranteActual;
                    }

                    if (CuadranteActual != 0 && CuadranteActual != CuadranteAnterior)
                    {
                        //evalúa si se suman pasos por cuadrantes o se restan
                        int SaltoCuadrantes = CuadranteActual - CuadranteAnterior;
                        if (SaltoCuadrantes == 1 || SaltoCuadrantes == -1)
                        {
                            //paso a un cuadrante adyacente
                            if (SaltoCuadrantes > 0)
                            {
                                ConteoCuadrantes += SaltoCuadrantes;
                            }
                        }
                        else if (SaltoCuadrantes == 2 || SaltoCuadrantes == -2)
                        {
                            //Evalúa si el salto de dos cuadrantes se realiza en sentido horario (-) o no (+);
                            int SignoSalto = Segmento.Lado(pAnt, p, Pto);
                            if (SignoSalto == 0)
                            {
                                //el punto se encuentra en la frontera del polígono
                                Res = true;
                                break;
                            }
                            else
                            {
                                ConteoCuadrantes += SignoSalto * 2;
                            }
                        }
                        else if (SaltoCuadrantes == 3 || SaltoCuadrantes == -3)
                        {
                            //salto entre el cuadrante 4 y el 1
                            //se invierte el SaltoCuadrante
                            ConteoCuadrantes -= SaltoCuadrantes / 3;
                        }
                    }
                    else
                    {
                        //puntos coincidentes o en el mismo cuadrante se omiten
                        //pertenece al polígono
                        Res = true;
                        break;
                    }
                    pAnt = p;
                }

                if (!Res)
                {
                    //evalua si se ha producido una revolución
                    if (ConteoCuadrantes >= 4 || ConteoCuadrantes <= -4)
                    {
                        Res = true;
                    }

                    /*else
                     * {
                     *  Res = false;
                     * }*/
                }

                /*else
                 * {
                 *  //salida forzada porcoincidencia etre punto y vértice
                 *  Res = true;
                 * }*/
            }

            return(Res);
        }