Skip to content

Instantly share code, notes, and snippets.

@elivlo
Last active November 10, 2021 18:39
Show Gist options
  • Save elivlo/964d877662738c5cc3423968ea502192 to your computer and use it in GitHub Desktop.
Save elivlo/964d877662738c5cc3423968ea502192 to your computer and use it in GitHub Desktop.
Search for triangles in a list of straights
/*
* Created together with:
* @github.com/JanielGamer
* */
import java.awt.Dimension;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import javafx.scene.control.TextArea;
public class DreieckeZaehlen {
// Listen für die Geraden und für die gefundenen Dreiecke
static ArrayList<Gerade> geraden = new ArrayList<Gerade>();
static ArrayList<Gerade[]> dreiecke = new ArrayList<Gerade[]>();
/*
* Test Programm
*
* public static void main(String [] args) { //geraden.add(new Gerade(0, 0,
* 0, 200)); //geraden.add(new Gerade(0, 0, 120, 0)); //geraden.add(new
* Gerade(120, 0, 0, 200)); //geraden.add(new Gerade(0, 20, 100, 180));
* //geraden.add(new Gerade(20, 0, 50, 180)); //geraden.add(new Gerade(100,
* 0, 50, 180));
*
*
* ladeFile(new File("Dreiecke.txt"));
*
* System.out.println(zaehleDreiecke()); }
*/
//Methode zum Herausfinden eines Schnittpunktes
public static double[] schnittpunkt(Gerade a, Gerade b) {
// erstellt Schnittpunkt-Array
double[] sp = new double[3];
double r;
// formt die Geradengleichung um und löst sie auf
if (a.getX2() - a.getX1() != 0 && b.getY2() - b.getY1() != 0) {
r = (b.getX1() - a.getX1()
+ (((b.getX2() - b.getX1()) * (a.getY1() - b.getY1())) / (b.getY2() - b.getY1())))
/ ((a.getX2() - a.getX1())
- (((a.getY2() - a.getY1()) * (b.getX2() - b.getX1())) / (b.getY2() - b.getY1())));
sp[0] = a.getX1() + r * (a.getX2() - a.getX1());
sp[1] = a.getY1() + r * (a.getY2() - a.getY1());
sp[2] = 1;
} else if (a.getY2() - a.getY1() != 0 && b.getX2() - b.getX1() != 0) {
r = (b.getY1() - a.getY1()
+ (((b.getY2() - b.getY1()) * (a.getX1() - b.getX1())) / (b.getX2() - b.getX1())))
/ ((a.getY2() - a.getY1())
- (((a.getX2() - a.getX1()) * (b.getY2() - b.getY1())) / (b.getX2() - b.getX1())));
sp[0] = a.getX1() + r * (a.getX2() - a.getX1());
sp[1] = a.getY1() + r * (a.getY2() - a.getY1());
sp[2] = 1;
} else {
sp[0] = 0;
sp[1] = 0;
sp[2] = 0;
}
// Diese Zeilen prüfen, ob der Schnittpunkt auf der Strecke liegt und
// nicht außerhalb
if (a.getX1() > a.getX2()) {
if (sp[0] < a.getX2() || a.getX1() < sp[0]) {
sp[2] = 0;
return sp;
}
} else {
if (sp[0] < a.getX1() || a.getX2() < sp[0]) {
sp[2] = 0;
return sp;
}
}
if (b.getX1() > b.getX2()) {
if (sp[0] < b.getX2() || b.getX1() < sp[0]) {
sp[2] = 0;
return sp;
}
} else {
if (sp[0] < b.getX1() || b.getX2() < sp[0]) {
sp[2] = 0;
return sp;
}
}
if (a.getY1() > a.getY2()) {
if (sp[1] < a.getY2() || a.getY1() < sp[1]) {
sp[2] = 0;
return sp;
}
} else {
if (sp[1] < a.getY1() || a.getY2() < sp[1]) {
sp[2] = 0;
return sp;
}
}
if (b.getY1() > b.getY2()) {
if (sp[1] < b.getY2() || b.getY1() < sp[1]) {
sp[2] = 0;
return sp;
}
} else {
if (sp[1] < b.getY1() || b.getY2() < sp[1]) {
sp[2] = 0;
return sp;
}
}
return sp;
}
// die Methode bekommt drei geraden
public static boolean pruefeDreieck(Gerade a, Gerade b, Gerade c) {
// Prüft, ob sich die drei Geraden untereinander schneiden
double ab[] = schnittpunkt(a, b);
double ac[] = schnittpunkt(a, c);
double bc[] = schnittpunkt(b, c);
// testet, ob es die gleiche Gerade ist
if (a == b || b == c || a == c) {
return false;
}
// diese if-Clause testet, ob der Schnittpunkt in der Strecke vorkommt
// und nicht darüber hinaus
if ((ab[2] == 1 && ac[2] == 1 && bc[2] == 1)
&& !(ab[0] == ac[0] && ac[0] == bc[0] && ab[1] == ac[1] && ac[1] == bc[1])) {
Gerade[] dreieck = { a, b, c };
dreiecke.add(dreieck);
return true;
}
return false;
}
//Hauptmethode um die Dreiecke zu zählen
public static int zaehleDreiecke() {
int dreieckCounter = 0;
// macht eine Schleife um jede Gerade mit jeder zu vergleichen
for (int x = 0; x < geraden.size() - 2; x++) {
for (int y = x + 1; y < geraden.size() - 1; y++) {
for (int z = y + 1; z < geraden.size(); z++) {
// wenn die Geraden sich kreuzen, dann wird das Dreieck hinzugefügt
if (pruefeDreieck(geraden.get(x), geraden.get(y), geraden.get(z))) {
dreieckCounter++;
}
}
}
}
// Gibt Dreiecke in der Konsole aus, mit den sich kreuzenden Geraden
for (Gerade[] x : dreiecke) {
System.out.println(x[0].nummer + " - " + x[1].nummer + " - " + x[2].nummer);
}
return dreieckCounter;
}
// Ließt die ausgewählte Datei aus
public static void ladeFile(File file, TextArea console) {
String input;
String[] inputZahl = new String[4];
// Versucht die Datei zu laden
try {
BufferedReader reader = new BufferedReader(new FileReader(file));
// lädt die erste Zeile aus um sie herauszufiltern
reader.readLine();
// lädt jede Zeile der Dreieckdatei
while ((input = reader.readLine()) != null) {
inputZahl = input.split(" ");
// Gerade(x1, y1, x2, y2)
geraden.add(new Gerade(Double.parseDouble(inputZahl[0]), Double.parseDouble(inputZahl[1]),
Double.parseDouble(inputZahl[2]), Double.parseDouble(inputZahl[3])));
}
reader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Main.printlnConsole("Laden fertig!", console);
}
// Errechnet die Skalierung
public static int getScale() {
Dimension screensize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
int scale;
double x1 = 0, y1 = 0;
// sucht die größten Punkte der Geraden raus
for (Gerade gerade : geraden) {
if (gerade.getX1() > gerade.getX2()) {
if (gerade.getX1() > x1) {
x1 = gerade.getX1();
}
} else {
if (gerade.getX2() > x1) {
x1 = gerade.getX2();
}
}
if (gerade.getY1() > gerade.getY2()) {
if (gerade.getY1() > y1) {
y1 = gerade.getY1();
}
} else {
if (gerade.getY2() > y1) {
y1 = gerade.getY2();
}
}
}
// brechnet die Skalierung aufgrund der größten Punkte
if (x1 > y1) {
scale = (int) (screensize.width / x1 / 1.5);
} else {
scale = (int) (screensize.height / y1 / 1.5);
}
return scale;
}
}
/*
* Created together with:
* @github.com/JanielGamer
* */
/*
* Klasse um die einzelnen Geraden mit den Start und Endpunkten abzuspeichern!
* Dabei bekommt jede Gerade eine eigene ID (nummer).
*
* */
class Gerade {
// statische Variable um die ID zu setzen
static int zaehler = 0;
// Punkte der Gerade
private double x1;
private double x2;
private double y1;
private double y2;
// ID der Geraden
public int nummer;
//Konstruktor
Gerade(double x1, double y1, double x2, double y2) {
setX1(x1);
setX2(x2);
setY1(y1);
setY2(y2);
nummer = zaehler;
zaehler++;
}
// Getter und Setter
public double getX1() {
return x1;
}
public void setX1(double x1) {
this.x1 = x1;
}
public double getX2() {
return x2;
}
public void setX2(double x2) {
this.x2 = x2;
}
public double getY1() {
return y1;
}
public void setY1(double y1) {
this.y1 = y1;
}
public double getY2() {
return y2;
}
public void setY2(double y2) {
this.y2 = y2;
}
}
/*
* Created together with:
* @github.com/JanielGamer
* */
import java.awt.Dimension;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextArea;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Line;
import java.io.Console;
import java.io.File;
import java.util.ArrayList;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
//Auslesen der Benutzer Bildschrimgröße
Dimension screensize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
//Wichtigsten Elemente der GUI
BorderPane root = new BorderPane();
ScrollPane scrollPane = new ScrollPane();
Pane pane = new Pane();
TextArea console = new TextArea();
console.setEditable(false);
Scene scene = new Scene(root, screensize.width, screensize.height - 60);
//ListView um die gefundenen Dreiecke auszuwählen
ListView<Integer> listView = new ListView<Integer>();
ArrayList<Line[]> lines = new ArrayList<>();
ObservableList<Integer> linesName = FXCollections.observableArrayList();
//Startknopf plus Actionlistener
Button button = new Button("Lade Dreieck");
button.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
//Datei Vorbereitung
File file;
FileChooser fileChooser = new FileChooser();
//Dateiloader
file = fileChooser.showOpenDialog(primaryStage);
if(file == null)
System.exit(1);
//nach erfold des Ladens ausblenden der unwichtigen Elemente
button.setVisible(false);
root.setBottom(console);
//Methode um die Datei auszulesen und zu berechnen
DreieckeZaehlen.ladeFile(file, console);
printlnConsole(String.valueOf(DreieckeZaehlen.zaehleDreiecke()) + " Dreiecke wurden gefunden.", console);
//Sinvolles skalieren der Anzeige
int scale = DreieckeZaehlen.getScale();
//Schleife um die Geraden anzuzeigen
for(Gerade x : DreieckeZaehlen.geraden){
pane.getChildren().add(new Line(x.getX1() * scale, x.getY1() * scale,
x.getX2() * scale, x.getY2() * scale));
}
// Fügt eine rote Umrandung bei den Dreiecken hinzu und macht sie unsichtbar
int counter = 1;
for (Gerade[] x : DreieckeZaehlen.dreiecke) {
double[] sp1 = DreieckeZaehlen.schnittpunkt(x[0], x[1]);
double[] sp2 = DreieckeZaehlen.schnittpunkt(x[1], x[2]);
double[] sp3 = DreieckeZaehlen.schnittpunkt(x[0], x[2]);
Line[] a = { new Line(sp1[0] * scale, sp1[1] * scale, sp2[0] * scale, sp2[1] * scale),
new Line(sp2[0] * scale, sp2[1] * scale, sp3[0] * scale, sp3[1] * scale),
new Line(sp1[0] * scale, sp1[1] * scale, sp3[0] * scale, sp3[1] * scale) };
a[0].setStroke(Color.RED);
a[1].setStroke(Color.RED);
a[2].setStroke(Color.RED);
a[0].setStrokeWidth(5);
a[1].setStrokeWidth(5);
a[2].setStrokeWidth(5);
lines.add(a);
pane.getChildren().add(a[0]);
pane.getChildren().add(a[1]);
pane.getChildren().add(a[2]);
a[0].setVisible(false);
a[1].setVisible(false);
a[2].setVisible(false);
linesName.add(counter);
counter++;
}
// Ein Actionlistener für die Liste mit den gefundenen Dreiecke
listView.setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
//blendet alle roten Umrandungen aus
for (Line[] x : lines) {
x[0].setVisible(false);
x[1].setVisible(false);
x[2].setVisible(false);
}
//macht eine rote Umrandung um das ausgewählte Dreieck
lines.get(listView.getSelectionModel().getSelectedIndex())[0].setVisible(true);
lines.get(listView.getSelectionModel().getSelectedIndex())[1].setVisible(true);
lines.get(listView.getSelectionModel().getSelectedIndex())[2].setVisible(true);
}
});
listView.setItems(linesName);
scrollPane.setScaleY(-1);
pane.setTranslateY(20);
pane.setTranslateX(20);
}
});
scrollPane.setContent(pane);
root.setTop(button);
root.setCenter(scrollPane);
root.setRight(listView);
primaryStage.setScene(scene);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
//Mainmethode startet die JavaFX Application
public static void main(String[] args) {
launch(args);
}
//Methode um in die Konsole der JavaFX Application zu schreiben, mit Absatz
public static void printlnConsole(String input, TextArea console) {
console.setText(console.getText() + input + "\n");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment