コード例 #1
0
 private void _Inicializa()
 {
     Minimos = new Punto();
     Maximos = new Punto();
 }
コード例 #2
0
        public double Distancia(Punto Pto)
        {
            double Res = Math.Sqrt(Math.Pow(this.X - Pto.X, 2) + Math.Pow(this.Y - Pto.Y, 2) + Math.Pow(this.Z - Pto.Z, 2));

            return(double.Parse(Res.ToString()));
        }
コード例 #3
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);
        }
コード例 #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);
        }
コード例 #5
0
 public void AddPunto(int Indice, Punto Punto)
 {
     _area = double.NaN; //ya no es válido cualquier valor anterior del área.
     _Puntos.Insert(Indice, Punto);
     Bownding.Actualizar(Punto);
 }