package preseci_krugova;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class TraziPreseke {
private class PoredjenjeDogadjaja implements Comparator<Dogadjaj> {
@Override
public int compare(Dogadjaj d1, Dogadjaj d2) {
long x1 = (d1.isPocetak()) ? (d1.getKrug().getCentar().getX() - d1.getKrug().getPoluprecnik()) :
(d1.getKrug().getCentar().getX() + d1.getKrug().getPoluprecnik());
long x2 = (d2.isPocetak()) ? (d2.getKrug().getCentar().getX() - d2.getKrug().getPoluprecnik()) :
(d2.getKrug().getCentar().getX() + d2.getKrug().getPoluprecnik());
if (x1 == x2) {
if (d1.isPocetak()) {
return -1;
} else if (d2.isPocetak()) {
return 1;
} else {
return 0;
}
}
return (int)(x1-x2);
}
}
private ArrayList<Krug> sviKrugovi;
private ArrayList<Krug> aktivniKrugovi;
private ArrayList<Dogadjaj> dogadjaji;
private int indDogadjaja;
private boolean aktivno = false;
private int brPreseka;
private Krug prosli;
private Crtanje crtanje;
public TraziPreseke() {
crtanje = new Crtanje();
sviKrugovi = new ArrayList<Krug>();
aktivniKrugovi = new ArrayList<Krug>();
dogadjaji = new ArrayList<Dogadjaj>();
}
public boolean gotovo() {
if (!aktivno) {
return true;
}
return indDogadjaja >= dogadjaji.size();
}
public void dodajKrug(Krug k) {
sviKrugovi.add(k);
}
public void brisiKrug(Krug k) {
sviKrugovi.remove(k);
}
public void brisiKrugove() {
sviKrugovi.clear();
}
public void traziPreseke() {
aktivniKrugovi.clear();
dogadjaji.clear();
aktivno = true;
indDogadjaja = 0;
brPreseka = 0;
for (Krug krug : sviKrugovi) {
dogadjaji.add(new Dogadjaj(krug, true));
dogadjaji.add(new Dogadjaj(krug, false));
}
Collections.sort(this.dogadjaji, new PoredjenjeDogadjaja());
naredniKorak();
}
public ArrayList<Krug> getSviKrugovi() {
return sviKrugovi;
}
public BufferedImage crtaj() {
return crtanje.crtaj(sviKrugovi);
}
public int getBrPreseka() {
return brPreseka;
}
public boolean naredniKorak() {
if (prosli != null) {
if (prosli.getStatus() == StatusKruga.TrenutniKraj) {
prosli.setStatus(StatusKruga.Prosao);
} else if (prosli.getStatus() == StatusKruga.TrenutniPocetak) {
prosli.setStatus(StatusKruga.Aktivan);
}
prosli = null;
}
Dogadjaj trenutniDogadjaj = dogadjaji.get(indDogadjaja);
if (!trenutniDogadjaj.isPocetak()) {
aktivniKrugovi.remove(trenutniDogadjaj.getKrug());
trenutniDogadjaj.getKrug().setStatus(StatusKruga.TrenutniKraj);
for (Krug prethodniKrug : aktivniKrugovi) {
prethodniKrug.setStatus(StatusKruga.Aktivan);
}
} else {
for (Krug prethodniKrug : aktivniKrugovi) {
int preseci = sekuSe(prethodniKrug, trenutniDogadjaj.getKrug());
brPreseka += preseci;
if (preseci > 0) {
prethodniKrug.setStatus(StatusKruga.Presek);
} else {
prethodniKrug.setStatus(StatusKruga.Aktivan);
}
}
aktivniKrugovi.add(trenutniDogadjaj.getKrug());
trenutniDogadjaj.getKrug().setStatus(StatusKruga.TrenutniPocetak);
}
prosli = trenutniDogadjaj.getKrug();
indDogadjaja++;
if (gotovo()) {
aktivno = false;
return false;
}
return true;
}
private int sekuSe(Krug prethodniKrug, Krug trenutniKrug) {
double d = Util.dist(prethodniKrug.getCentar(), trenutniKrug.getCentar());
//da li je centar jednog unutar drugog
if (d >= prethodniKrug.getPoluprecnik() && d >= trenutniKrug.getPoluprecnik()) { //ako nije
if (d < prethodniKrug.getPoluprecnik() + trenutniKrug.getPoluprecnik()) {
return 2;
} else if (d == prethodniKrug.getPoluprecnik() + trenutniKrug.getPoluprecnik()) {
return 1;
} else {
return 0;
}
} else { //ako jeste
//utvrdimo koji je "unutrasnji", a koji "spoljasnji"
Krug unutrasnji, spoljasnji;
if (d < prethodniKrug.getPoluprecnik()) {
spoljasnji = prethodniKrug;
unutrasnji = trenutniKrug;
} else {
spoljasnji = trenutniKrug;
unutrasnji = prethodniKrug;
}
if (d > spoljasnji.getPoluprecnik() - unutrasnji.getPoluprecnik()) {
return 2;
} else if (d == spoljasnji.getPoluprecnik() - unutrasnji.getPoluprecnik()) {
return 1;
} else {
return 0;
}
}
}
public void resetujStatusKrugova() {
for (Krug k : sviKrugovi) {
k.setStatus(StatusKruga.Neposecen);
}
}
public static void main(String[] args) {
ArrayList<Krug> krugovi = new ArrayList<Krug>();
TraziPreseke traziPreseke = new TraziPreseke();
napuniKrugove(krugovi);
for (Krug krug : krugovi) {
traziPreseke.dodajKrug(krug);
}
traziPreseke.traziPreseke();
while (traziPreseke.naredniKorak()) ;
System.out.println("Ima " + traziPreseke.getBrPreseka() + " preseka");
}
private static void napuniKrugove(ArrayList<Krug> krugovi) {
//treba da vrate 10 preseka
krugovi.add(new Krug(new Tacka(3, 3), 3));
krugovi.add(new Krug(new Tacka(4, 3), 1));
krugovi.add(new Krug(new Tacka(6, 3), 5));
krugovi.add(new Krug(new Tacka(10, 3), 6));
krugovi.add(new Krug(new Tacka(8, 3), 10));
krugovi.add(new Krug(new Tacka(17, 3), 1));
}
public Crtanje getCrtanje() {
return crtanje;
}
public Krug selektuj(int x, int y) {
Rectangle2D rect = new Rectangle2D.Double(x, y, 1, 1);
for (Krug k : sviKrugovi) {
Point2D centar = Util.transformisiTackuUMis(k.getCentar());
long kX = (long)centar.getX() - k.getPoluprecnik();
long kY = (long)centar.getY() - k.getPoluprecnik();
Ellipse2D e = new Ellipse2D.Double(kX, kY, k.getPoluprecnik()*2, k.getPoluprecnik()*2);
if (e.intersects(rect)) {
return k;
}
}
return null;
}
}