/* package whatever; // don't place package name! */
import java.util.*;
import java.lang.*;
import java.io.*;
class Ponto {
public double x, y;
public Ponto(double x, double y) {
this.x = x;
this.y = y;
}
}
class Aresta {
private Ponto inicio, fim;
public Aresta(Ponto i, Ponto f) {
inicio = i;
fim = f;
}
public Ponto getInicio() {
if (inicio == null)
inicio = new Ponto(0,0);
return inicio;
}
public Ponto getFim() {
if (fim == null)
fim = new Ponto(0,0);
return fim;
}
public void setInicio(Ponto i) {
this.inicio = i;
}
public void setFim(Ponto f) {
this.fim = f;
}
public boolean verificaSePtoInterceptaArestaPelaDireita(Ponto p) {
Ponto p1 = getInicio();
Ponto p2 = getFim();
double ymin
= Math.
min(p1.
y, p2.
y); double ymax
= Math.
max(p1.
y, p2.
y);
double y = p.y;
double x = p1.x + (y-p1.y)*(p2.x-p1.x)/(p2.y-p1.y);
boolean estaAEsquerda = p.x < x;
boolean interceptaSegmento = y >= ymin && y <= ymax;
return estaAEsquerda && interceptaSegmento;
}
}
class Poligono {
public List<Aresta> arestas;
public Poligono(List<Aresta> a) {
setArestas(a);
}
public List<Aresta> getArestas() {
if (arestas == null) {
arestas = new ArrayList<Aresta>();
}
return arestas;
}
public void setArestas(List<Aresta> arestas) {
this.arestas = arestas;
}
public boolean isDentroDoPoligono(Ponto p) {
int numeroDeArestasInterceptadas = 0;
Iterator<Aresta> i = getArestas().iterator();
while (i.hasNext()) {
if (i.next().verificaSePtoInterceptaArestaPelaDireita(p)) {
numeroDeArestasInterceptadas++;
}
}
return numeroDeArestasInterceptadas % 2 == 1;
}
}
class Teste {
public static void main
(String args
[]) { Aresta a1 = new Aresta(new Ponto(0,0), new Ponto(0,1));
Aresta a2 = new Aresta(new Ponto(0,1), new Ponto(1,1));
Aresta a3 = new Aresta(new Ponto(1,1), new Ponto(1,0));
Aresta a4 = new Aresta(new Ponto(1,0), new Ponto(0,0));
List<Aresta> arestas = new ArrayList<Aresta>();
arestas.add(a1);
arestas.add(a2);
arestas.add(a3);
arestas.add(a4);
Poligono p = new Poligono(arestas);
int pontosDentro = 0;
int totalDePontos = 1000000;
double ladoQuadrado = 2;
for (int i = 0; i < totalDePontos; i++) {
Ponto ponto
= new Ponto
(Math.
random()*ladoQuadrado,
Math.
random()*ladoQuadrado
); if (p.isDentroDoPoligono(ponto))
pontosDentro++;
}
double relacaoEntreAreas = (1.0*pontosDentro/totalDePontos);
System.
out.
println("Relação: " + relacaoEntreAreas
); }
}
LyogcGFja2FnZSB3aGF0ZXZlcjsgLy8gZG9uJ3QgcGxhY2UgcGFja2FnZSBuYW1lISAqLwoKaW1wb3J0IGphdmEudXRpbC4qOwppbXBvcnQgamF2YS5sYW5nLio7CmltcG9ydCBqYXZhLmlvLio7CgpjbGFzcyBQb250byB7CglwdWJsaWMgZG91YmxlIHgsIHk7CglwdWJsaWMgUG9udG8oZG91YmxlIHgsIGRvdWJsZSB5KSB7CgkJdGhpcy54ID0geDsKCQl0aGlzLnkgPSB5OwoJfQp9CgpjbGFzcyBBcmVzdGEgewoJcHJpdmF0ZSBQb250byBpbmljaW8sIGZpbTsKCXB1YmxpYyBBcmVzdGEoUG9udG8gaSwgUG9udG8gZikgewoJCWluaWNpbyA9IGk7CgkJZmltID0gZjsKCX0KCXB1YmxpYyBQb250byBnZXRJbmljaW8oKSB7CgkJaWYgKGluaWNpbyA9PSBudWxsKQoJCQlpbmljaW8gPSBuZXcgUG9udG8oMCwwKTsKCQlyZXR1cm4gaW5pY2lvOwoJfQoJcHVibGljIFBvbnRvIGdldEZpbSgpIHsKCQlpZiAoZmltID09IG51bGwpCgkJCWZpbSA9IG5ldyBQb250bygwLDApOwoJCXJldHVybiBmaW07Cgl9CglwdWJsaWMgdm9pZCBzZXRJbmljaW8oUG9udG8gaSkgewoJCXRoaXMuaW5pY2lvID0gaTsKCX0KCXB1YmxpYyB2b2lkIHNldEZpbShQb250byBmKSB7CgkJdGhpcy5maW0gPSBmOwoJfQoJcHVibGljIGJvb2xlYW4gdmVyaWZpY2FTZVB0b0ludGVyY2VwdGFBcmVzdGFQZWxhRGlyZWl0YShQb250byBwKSB7CgkJUG9udG8gcDEgPSBnZXRJbmljaW8oKTsKCQlQb250byBwMiA9IGdldEZpbSgpOwoJCQoJCWRvdWJsZSB5bWluID0gTWF0aC5taW4ocDEueSwgcDIueSk7CgkJZG91YmxlIHltYXggPSBNYXRoLm1heChwMS55LCBwMi55KTsKCQkKCQlkb3VibGUgeSA9IHAueTsKCQlkb3VibGUgeCA9IHAxLnggKyAoeS1wMS55KSoocDIueC1wMS54KS8ocDIueS1wMS55KTsKCQkKCQlib29sZWFuIGVzdGFBRXNxdWVyZGEgPSBwLnggPCB4OwoJCWJvb2xlYW4gaW50ZXJjZXB0YVNlZ21lbnRvID0geSA+PSB5bWluICYmIHkgPD0geW1heDsKCQlyZXR1cm4gZXN0YUFFc3F1ZXJkYSAmJiBpbnRlcmNlcHRhU2VnbWVudG87Cgl9Cn0KCmNsYXNzIFBvbGlnb25vIHsKCXB1YmxpYyBMaXN0PEFyZXN0YT4gYXJlc3RhczsKCQoJcHVibGljIFBvbGlnb25vKExpc3Q8QXJlc3RhPiBhKSB7CgkJc2V0QXJlc3RhcyhhKTsKCX0KCXB1YmxpYyBMaXN0PEFyZXN0YT4gZ2V0QXJlc3RhcygpIHsKCQlpZiAoYXJlc3RhcyA9PSBudWxsKSB7CgkJCWFyZXN0YXMgPSBuZXcgQXJyYXlMaXN0PEFyZXN0YT4oKTsKCQl9CgkJcmV0dXJuIGFyZXN0YXM7Cgl9CglwdWJsaWMgdm9pZCBzZXRBcmVzdGFzKExpc3Q8QXJlc3RhPiBhcmVzdGFzKSB7CgkJdGhpcy5hcmVzdGFzID0gYXJlc3RhczsKCX0KCQoJcHVibGljIGJvb2xlYW4gaXNEZW50cm9Eb1BvbGlnb25vKFBvbnRvIHApIHsKCQlpbnQgbnVtZXJvRGVBcmVzdGFzSW50ZXJjZXB0YWRhcyA9IDA7CgkJSXRlcmF0b3I8QXJlc3RhPiBpID0gZ2V0QXJlc3RhcygpLml0ZXJhdG9yKCk7CgkJd2hpbGUgKGkuaGFzTmV4dCgpKSB7CgkJCWlmIChpLm5leHQoKS52ZXJpZmljYVNlUHRvSW50ZXJjZXB0YUFyZXN0YVBlbGFEaXJlaXRhKHApKSB7CgkJCQludW1lcm9EZUFyZXN0YXNJbnRlcmNlcHRhZGFzKys7CgkJCX0KCQl9CgkJCgkJcmV0dXJuIG51bWVyb0RlQXJlc3Rhc0ludGVyY2VwdGFkYXMgJSAyID09IDE7Cgl9Cn0KCmNsYXNzIFRlc3RlIHsKCXB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZyBhcmdzW10pIHsKCQlBcmVzdGEgYTEgPSBuZXcgQXJlc3RhKG5ldyBQb250bygwLDApLCBuZXcgUG9udG8oMCwxKSk7CgkJQXJlc3RhIGEyID0gbmV3IEFyZXN0YShuZXcgUG9udG8oMCwxKSwgbmV3IFBvbnRvKDEsMSkpOwoJCUFyZXN0YSBhMyA9IG5ldyBBcmVzdGEobmV3IFBvbnRvKDEsMSksIG5ldyBQb250bygxLDApKTsKCQlBcmVzdGEgYTQgPSBuZXcgQXJlc3RhKG5ldyBQb250bygxLDApLCBuZXcgUG9udG8oMCwwKSk7CgkJCgkJTGlzdDxBcmVzdGE+IGFyZXN0YXMgPSBuZXcgQXJyYXlMaXN0PEFyZXN0YT4oKTsKCQlhcmVzdGFzLmFkZChhMSk7CgkJYXJlc3Rhcy5hZGQoYTIpOwoJCWFyZXN0YXMuYWRkKGEzKTsKCQlhcmVzdGFzLmFkZChhNCk7CgkJCgkJUG9saWdvbm8gcCA9IG5ldyBQb2xpZ29ubyhhcmVzdGFzKTsKCQkKCQlpbnQgcG9udG9zRGVudHJvID0gMDsKCQlpbnQgdG90YWxEZVBvbnRvcyA9IDEwMDAwMDA7CgkJCgkJZG91YmxlIGxhZG9RdWFkcmFkbyA9IDI7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCB0b3RhbERlUG9udG9zOyBpKyspIHsKCQkJUG9udG8gcG9udG8gPSBuZXcgUG9udG8oTWF0aC5yYW5kb20oKSpsYWRvUXVhZHJhZG8sIE1hdGgucmFuZG9tKCkqbGFkb1F1YWRyYWRvKTsKCQkJaWYgKHAuaXNEZW50cm9Eb1BvbGlnb25vKHBvbnRvKSkKCQkJCXBvbnRvc0RlbnRybysrOwoJCX0KCQlkb3VibGUgcmVsYWNhb0VudHJlQXJlYXMgPSAoMS4wKnBvbnRvc0RlbnRyby90b3RhbERlUG9udG9zKTsKCQlTeXN0ZW0ub3V0LnByaW50bG4oIlJlbGHDp8OjbzogIiArIHJlbGFjYW9FbnRyZUFyZWFzKTsKCX0KfQ==