// Last edited on 2000-09-05 02:53:27 by stolfi import Bairro; import Logradouro; import Ponto; import Retangulo; import TipoDeServico; import Trecho; import java.lang.Math; import java.util.Vector; public class ServicoImpl extends Servico { //Variaveis internas private int _id; private String _nome; private Logradouro _logradouro; private String _complemento; private Trecho[] _trEnt; private Trecho[] _trSai; private Ponto[] _rampas; private Ponto _centro; private Ponto[] _vertices; private TipoDeServico _tipo; // ** MÉTODOS DE CONSTRUÇÃO ** public ServicoImpl(int id) { this._id = id; } public void inicializa( String nome, Logradouro logr, String compl, Ponto centro, Vector listaVert, Vector listaEnt, Vector listaSai, TipoDeServico tipo ) { this._nome = nome; this._logradouro = logr; this._complemento = compl; this._centro = new Ponto(centro.x, centro.y); this._vertices = pegaPontos(listaVert); this._trEnt = pegaTrechos(listaEnt); this._trSai = pegaTrechos(listaSai); this._tipo = tipo; this._rampas = null; // por enquanto. } // ** MÉTODOS PÚBLICOS GERAIS DE ELEMENTOS ** public int id() { return this._id; } public String nome() { return this._nome; } public String toString() { return "s" + id(); } public Bairro bairro() { return null; } public Ponto centro() { return this._centro; } public void insere(Retangulo r) { Ponto[] v = vertices(); for (int i = 0; i < v.length; i++) { Ponto p = v[i]; r.insereXY(p.x, p.y); } } public boolean intercepta(Retangulo r) { Ponto[] v = vertices(); for (int i = 0; i < v.length; i++) { Ponto p = v[i]; if (r.contem(p.x, p.y)) { return true; } } return false; } public double distancia(Ponto p) { double minDist = Ponto.distancia(p, centro()); Ponto[] v = vertices(); for (int i = 0; i < v.length; i++) { double dist = Ponto.distancia(p, v[i]); if (dist < minDist) { minDist = dist; } } return minDist; } // ** MÉTODOS PÚBLICOS ESPECÍFICOS ** public Logradouro logradouro() { return this._logradouro; } public String complemento() { return this._complemento; } public Ponto[] vertices() { return(this._vertices); } public Trecho[] entradas() { return(this._trEnt); } public Trecho[] saidas() { return(this._trSai); } public TipoDeServico tipo() { return(this._tipo); } public Ponto[] rampas() { if (_rampas == null) { criaRampas(); } return _rampas; } // ** MÉTODOS USADOS INTERNAMENTE ** private Trecho[] pegaTrechos(Vector listaTrechos) { int n = listaTrechos.size(); Trecho[] tr = new Trecho[n]; for(int i = 0; i < n;i++) { tr[i] = (Trecho) listaTrechos.elementAt(i); } listaTrechos = null; return tr; } private Ponto[] pegaPontos(Vector listaPontos) { int n = listaPontos.size(); Ponto[] p = new Ponto[n]; for(int i = 0; i < n;i++) { p[i] = (Ponto) listaPontos.elementAt(i); } listaPontos = null; return p; } private void criaRampas() // O codigo abaixo determina os segmentos de ligacao entre um servico // e os trechos de entrada e saída. Estes são armazenados no array _rampas. { int Inicio_serv; int Fim_serv; double dist, minDist; Ponto minVertice; Ponto ini, fim; Trecho tr; int ng = _trEnt.length + _trSai.length; _rampas = new Ponto[2*ng]; for (int i = 0; i < ng; i++) { // Encontra o vértice mais próximo do trecho de ent/sai: minDist = Double.MAX_VALUE; minVertice = null; tr = (i < _trSai.length ? _trSai[i] : _trEnt[i - _trSai.length]); ini = tr.origPos(); fim = tr.destPos(); for (int j = 0; j < _vertices.length; j++) { dist = Ponto.distanciaASegmento(_vertices[j], ini, fim); if (dist < minDist) { minDist = dist; minVertice = _vertices[j]; } } Ponto p = new Ponto(); p.x = minVertice.x; p.y = minVertice.y; Ponto.projetaEmSegmento(p, ini, fim); _rampas[2*i] = minVertice; _rampas[2*i+1] = p; } } }