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); }
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); }
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); }
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); }
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); }