Eu tenho um objeto do tipo Shape e preciso testar se um ponto faz parte dos limites externos ou bounds desse shape. O metodo contains me retorna se o ponto esta dentro do shape. Por exemplo se o shape for um circulo ele me retorna true para todos os pontos dentro dos limites do circulo. Alguem ja passou por isso ou sabe como fazer ?
Faça dois laços for aninhados (um dentro do outro), o for externo iteranto um dos eixos entre o intervalo desse eixo que o shape está, e o for interno o outro eixo entre o intervalo desse eixo que o shape está. Dentro do for interno, verifique se o ponto está dentro do shape, e então imprima-o.
Uma dica muito útil para programar geometria: desenhe o que você precisa programar, faça anotações de programação em cima do objeto geométrico.
Tem que quebrar a cabeça inicialmente para aprender a programar esse tipo de programa.
Escrevi esse codigo baseado na sua ideia:
private HashMap<Point2D, Integer> createMap(Shape shape, BufferedImage b) {
HashMap<Point2D, Integer> mapa = new HashMap<Point2D, Integer>();
for (int x = 0; x < b.getWidth(); x++) {
for (int y = 0; y < b.getHeight(); y++) {
Point2D p = new Point2D.Double(x, y);
if (shape.contains(p)) {
mapa.put(p, b.getRGB(x, y));
}
}
}
return mapa;
}
Eu preciso de todos as cores da imagem nas posições ocupadas pelo shape. Esse método funciona no entanto nao pega alguns pontos. Alterei o tipo de x e y para double com passo 0.1. Nesse caso funcionou perfeitamente, mas a performance obviamente foi pro saco…
Eu queria mesmo era algo do tipo:
for (Point2D p : shape.getAllPointsInBounds()) {
mapa.put(p, b.getRGB((int) p.getX(), p.getY()));
}
Dei uma olhada no PathIterator mas acho que ele também não vai me ajudar. Preciso de ajuda para construir o metodo shape.getAllPointsInBounds().
Esse método que tu criou retorna todos os pontos, então tu pode aproveitá-lo, chamando-o dentro do método getAllPointsInBounds:
public Set getAllPointsInBounds(Shape shape, BufferedImage b) {
return createMap(shape, b).keySet();
}
Experimenta x e y como float para melhorar o desempenho. Operações com long e double são sempre mais lentas. Mas por que os pontos precisam ter casas decimais?
Outra questão, esses métodos não deveriam ser public?
Na verdade esse metodo nao existe!!! O que eu quis dizer e devo ter me expressado mal é que eu gostaria que existisse esse metodo na classe shape.
A dificuldade que estou tendo é exatamente essa, obter esse pontos.
Quando alterei x e y no for para double e disse que funcionou eu me enganei. O metodo shape.contains§ continuou retornando falso em situacoes em indesejadas.
Não sabia que float era mais rapido que double, vou alterar aqui no codigo…
Ah, ok!
Encontrei um erro: teu for está iterando até ser menor que o getWidth() e o getHeight(), e não está sendo menor ou igual. Ou seja, não está pegando os pontos que pertencem ao limite final do shape.
Vou postar o codigo que resolveu meu problema.
[code]static HashMap<Point2D, Integer> createMap(Shape shape, BufferedImage b) {
Rectangle2D r = shape.getBounds2D();
int xIni = (int) (r.getMinX() < 0 ? 0 : r.getMinX());
int yIni = (int) (r.getMinY() < 0 ? 0 : r.getMinY());
int xFim = (int) (r.getWidth() + xIni);
int yFim = (int) (r.getHeight() + yIni);
xFim = xFim > b.getWidth() ? b.getWidth() : xFim;
yFim = yFim > b.getHeight() ? b.getHeight() : yFim;
BasicStroke bs = new BasicStroke(2);
Shape shapeToMap = bs.createStrokedShape(shape);
HashMap<Point2D, Integer> mapa = new HashMap<Point2D, Integer>();
for (int x = xIni; x < xFim; x++) {
for (int y = yIni; y < yFim; y++) {
Point2D p = new Point2D.Double(x, y);
if (shape.contains(p)) {
mapa.put(p, b.getRGB(x, y));
}
}
}
return mapa;
}[/code]
Antes não estava funcionando porque o metodo contains retorna todos os pontos dentro do shape. Se o shape for do tipo Line2D contains sempre retorna 0, porque a area da linha eh zero. Utilizando createStrokedShape da classe BasicStroke o metodo contains acaba fazendo o que eu queria.