Last active
November 10, 2021 18:39
-
-
Save elivlo/964d877662738c5cc3423968ea502192 to your computer and use it in GitHub Desktop.
Search for triangles in a list of straights
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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