package de.edotzlaff.detection.detektion.berechnung; import android.os.Build; import androidx.annotation.RequiresApi; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Sets; import de.edotzlaff.detection.detektion.Detektionssignal; import de.edotzlaff.detection.detektion.Epizentrum; import de.edotzlaff.detection.detektion.berechnung.mathObjekte.Koordinaten; import de.edotzlaff.detection.detektion.berechnung.mathObjekte.Kreis; import de.edotzlaff.detection.detektion.berechnung.mathObjekte.Schnittpunkt; import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Set; public class EpizentrumRechnung { private static final double SCHRITTWEITE = 0.02; private static final double MAX_ABSTAND = 0.009; private static final int DOUBLESTELLEN = 8; @RequiresApi(api = Build.VERSION_CODES.O) public ArrayList initEndpunkte(ArrayList detektionssignal) { Detektionssignal nahegelegensteMessung = detektionssignal.get(0); ArrayList arrBerechnungsObjekte = new ArrayList<>(); for (int i = 1; i < detektionssignal.size(); i++) { if (detektionssignal.get(i).getAnkunftsZeit().isBefore(nahegelegensteMessung.getAnkunftsZeit())) { nahegelegensteMessung = detektionssignal.get(i); } } for (Detektionssignal aufzeichnung : detektionssignal) { int zeitunterschied = aufzeichnung.getAnkunftsZeit().getHour() * 3600 + aufzeichnung.getAnkunftsZeit().getMinute() * 60 + aufzeichnung.getAnkunftsZeit().getSecond() - nahegelegensteMessung.getAnkunftsZeit().getHour() * 3600 - nahegelegensteMessung.getAnkunftsZeit().getMinute() * 60 - nahegelegensteMessung.getAnkunftsZeit().getSecond(); double startradius = zeitunterschied * aufzeichnung.getGeschwErdbeben(); Endpunkt tempEndpunkt = new Endpunkt(aufzeichnung.getDeviceId()); Kreis k = new Kreis(aufzeichnung.getKoordinaten().getX(), aufzeichnung.getKoordinaten().getY(), startradius); tempEndpunkt.setKreis(k); arrBerechnungsObjekte.add(tempEndpunkt); } return arrBerechnungsObjekte; } public ArrayList berechneKreisSchnittpunkte(Kreis kreis1, Kreis kreis2) { ArrayList schnittpunkte = new ArrayList<>(); double dx = kreis2.getMittelPunkt().getX() - kreis1.getMittelPunkt().getX(); double dy = kreis2.getMittelPunkt().getY() - kreis1.getMittelPunkt().getY(); double c = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)); double x = ((Math.pow(kreis1.getRadius(), 2) + Math.pow(c, 2) - Math.pow(kreis2.getRadius(), 2))) / (2 * c); double y = Math.pow(kreis1.getRadius(), 2) - Math.pow(x, 2); //Kein Schnittpunkt vorhanden if (y < 0) { return schnittpunkte; } if (y > 0) { y = Math.sqrt(y); } double ex0 = dx / c; double ex1 = dy / c; double ey0 = -ex1; Schnittpunkt s1 = new Schnittpunkt(kreis1.getMittelPunkt().getX() + x * ex0, kreis1.getMittelPunkt().getY() + x * ex1); //Genau ein Schnittpunkt vorhanden if (y == 0) { schnittpunkte.add(s1); return schnittpunkte; } Schnittpunkt s2 = new Schnittpunkt(s1.getKoordinaten().getX() - y * ey0, s1.getKoordinaten().getY() - y * ex0); s1.getKoordinaten().setLocation(s1.getKoordinaten().getX() + y * ey0, s1.getKoordinaten().getY() + y * ex0); schnittpunkte.add(s1); schnittpunkte.add(s2); return schnittpunkte; } public boolean genuegendSchnittpunktevorhanden(ArrayList endpunktVerbindungen) { for (EndpunktVerbindung endpunktVerbindung : endpunktVerbindungen) { ArrayList templist; templist = berechneKreisSchnittpunkte(endpunktVerbindung.getEndpunkt1().getKreis(), endpunktVerbindung.getEndpunkt2().getKreis()); if (templist.isEmpty()) { return false; } endpunktVerbindung.setSchnittpunkte(templist); } return true; } public Epizentrum ueberpruefeObEpizentrum(ArrayList endpunktVerbindungen) { int counter; ArrayList schnittpunkte = new ArrayList<>(); for (Schnittpunkt s1 : endpunktVerbindungen.get(0).getSchnittpunkte()) { counter = 0; for (int i = 1; i < endpunktVerbindungen.size(); i++) { boolean bereitsSchnittpunktErmittelt = false; for (Schnittpunkt s2 : endpunktVerbindungen.get(i).getSchnittpunkte()) { double abstand = Math.sqrt( Math.pow(s2.getKoordinaten().getX() - s1.getKoordinaten().getX(), 2) + Math.pow(s2.getKoordinaten().getY() - s1.getKoordinaten().getY(), 2)); if (abstand < MAX_ABSTAND && !bereitsSchnittpunktErmittelt) { bereitsSchnittpunktErmittelt = true; counter++; schnittpunkte.add(s2); } if (counter == endpunktVerbindungen.size() - 1) { schnittpunkte.add(s1); Epizentrum tempEpizentrum = new Epizentrum(); tempEpizentrum.setKoordinaten(berechneEpizentrumKoordinaten(schnittpunkte)); return tempEpizentrum; } } } } return null; } public Koordinaten berechneEpizentrumKoordinaten(ArrayList schnittpunkte) { double x = 0; double y = 0; for (Schnittpunkt s : schnittpunkte) { x+= s.getKoordinaten().getX(); y+= s.getKoordinaten().getY(); } return new Koordinaten(new BigDecimal(x/schnittpunkte.size()).setScale(DOUBLESTELLEN, RoundingMode.HALF_UP).doubleValue(), new BigDecimal(y/schnittpunkte.size()).setScale(DOUBLESTELLEN, RoundingMode.HALF_UP).doubleValue()); } public ArrayList ermittleEndpunktKonbinationen(ArrayList tempBerechungsObjekte) { ArrayList verbindungen = new ArrayList<>(); Set> combinations = Sets.combinations(ImmutableSet.copyOf(tempBerechungsObjekte), 2); for (Set tempEndpunkt : combinations) { ArrayList helpArrayToGetValues = new ArrayList<>(tempEndpunkt); EndpunktVerbindung endpunktVerbindung = new EndpunktVerbindung(helpArrayToGetValues.get(0), helpArrayToGetValues.get(1)); verbindungen.add(endpunktVerbindung); } return verbindungen; } @RequiresApi(api = Build.VERSION_CODES.O) public LocalDateTime berechneEntstehungsZeitpunkt(Detektionssignal detektionssignal, Koordinaten koordEpi) { double abstand = Math.sqrt( Math.pow(detektionssignal.getKoordinaten().getX() - koordEpi.getX(), 2) + Math.pow(detektionssignal.getKoordinaten().getY() - koordEpi.getY(), 2)); int sec = (int) abstand/ detektionssignal.geschwErdbeben; return detektionssignal.getAnkunftsZeit().minusSeconds(sec); } public void erhoheRadius(ArrayList tempEndpunktListe) { for (Endpunkt b : tempEndpunktListe) { b.erhoeheRadius(SCHRITTWEITE); } } }