Pythagorastree

Nicolex3

Mitglied
Es geht um den Pythagorastree, ich soll den rekursiv einbauen. Ich habe kein Problem damit die Ordnung n=1 zu zeichnen, aber ich habe Probleme damit irgendwie einzubauen, dass wenn er nochmal in die Funktion springt, automatisch die neuen Koordinaten erkennt.

Vielen Dank im voraus.
 
K

kneitzel

Gast
Also wenn Du es rekursiv machst, dann solltest Du die Koordinaten entsprechend mitgeben.

Aber ohne Details, was Du genau machst, kann man Dir natürlich keine konkretere Hilfe anbieten....
 

Nicolex3

Mitglied
Das Problem ist, dass wir unsere eigene Bibliothek zur Verfügung gestellt bekommen haben, aber ich kann mal ungefähr zeigen, wie mein bisheriger Stand ist:

Java:
public class PythagorasTree {

    public static double sitesX (double angle, double x) {
        double p =  Math.cos(angle) * x;
        return Math.cos(angle) * p;
    }

    public static double sitesY (double angle, double y) {
        double p =  Math.cos(angle) * y;
        return Math.sin(angle) * p;
    }

    public static void drawH (int N ,double x, double y, double size) {

        if (N == 0) return;

        double angle = Math.PI/3;

        double x0 = x - size/5;
        double x1 = x + size/5;
        double y0 = y - size/5;
        double y1 = y + size/5;

        StdDraw.line(x0, y0, x0, y1);
        StdDraw.line(x1, y0, x1, y1);
        StdDraw.line(x0, y0, x1,  y0);
        StdDraw.line(x0, y1, x1,  y1);

        double gegenkatheteLaenge = Math.sin(angle) * (x1-x0);
        double ankatheteLaenge = Math.cos(angle) * (x1-x0);

        double rechtesQuadrat1 = gegenkatheteLaenge * Math.sin(angle);
        double rechtesQuadrat2 = gegenkatheteLaenge * Math.cos(angle);

        double linkesQuadrat1 = ankatheteLaenge * Math.sin(angle);
        double linkesQuadrat2 = ankatheteLaenge * Math.cos(angle);

        // Dreieck
        StdDraw.line(x0, y1, x0 + sitesX(angle, x1-x0), y1 + sitesY(angle, x1-x0));
        StdDraw.line(x1, y1, x0 + sitesX(angle, x1-x0), y1 + sitesY(angle, x1-x0));

        // Rechtes Quadrat
        StdDraw.line(x0 + sitesX(angle, x1-x0), y1 + sitesY(angle, x1-x0),
                x0 + sitesX(angle, x1-x0) + rechtesQuadrat2,
                y1 + sitesY(angle, x1-x0) + rechtesQuadrat1);

        StdDraw.line(x1,y1, x1 + rechtesQuadrat2,
                y1 + rechtesQuadrat1);

        StdDraw.line(x1 + rechtesQuadrat2,y1 + rechtesQuadrat1, x0 +
                        sitesX(angle, x1-x0) + rechtesQuadrat2,
                y1 + sitesY(angle, x1-x0) + rechtesQuadrat1);

        // Linkes Quadrat
        StdDraw.line(x0, y1, x0 - linkesQuadrat1, y1 + linkesQuadrat2);

        StdDraw.line(x0 + sitesX(angle, x1-x0) , y1 + sitesY(angle, x1-x0),
                x0 + sitesX(angle, x1-x0) - linkesQuadrat1, y1 + sitesY(angle, x1-x0) + linkesQuadrat2);

        StdDraw.line(x0 + sitesX(angle, x1-x0) - linkesQuadrat1,  y1 + sitesY(angle, x1-x0) + linkesQuadrat2
        , x0 - linkesQuadrat1, y1 + linkesQuadrat2);
       
    }

    public static void main(String[] args) {
        int N = 4;

        double x0 = 0.5 - 0.5/5;
        double x1 = 0.5 + 0.5/5;
        double y0 = 0.1 - 0.5/5;
        double y1 = 0.1 + 0.5/5;

        drawH(N, 0.5, .1, .5);
       

    }
}
 

Anhänge

  • Ausgabe.PNG
    Ausgabe.PNG
    5,2 KB · Aufrufe: 38
  • Veranschaulichung.PNG
    Veranschaulichung.PNG
    12,1 KB · Aufrufe: 51
Zuletzt bearbeitet:

Nicolex3

Mitglied
hei :),

das ist eine Methode, welche zwei Koordinaten als Argumente übernimmt und von der einen Koordinate zur anderen Koordinate eine Linie zeichnet: also z.B.

StdDraw.line(1, 2, 0, 0);

var1 = 1
var2 =2
und
var3= 0
var4 = 0

also (1,2) und (0,0)

Also würde jetzt eine Linie von (1,2) nach (0,0) gezeichnet
 

Nicolex3

Mitglied
Aso so war das gemeint 😅

Also, ich kriege es hin n = 1 zu zeichnen, da habe ich keine Probleme, aber wenn ich quasi wieder in die Funktion springe, dass ich genau das Quadrat links und rechts da wieder zwei Quadrate mache, sodass es perfekt darauf passt. Und der Winkel wird immer zufällig immer gebildet, der liegt zwischen 30 und 60 grad, also ich rede vom Winkel der links oben auf dem Quadrat sitzt, also das ist an sich kein Problem, also mit dem Winkel. Sorry, ich bin manchmal übel lost, aber sitze schon einige Stunden dran und ich weiß echt nicht, wie ich das lösen soll.
 
K

kneitzel

Gast
Also damit das rekursiv aufgebaut werden kann, müsstest Du es etwas mehr unterteilen.
- Du kannst das Qadrat malen
- Du kannst das Dreieck malen.


Damit die Methode rekursiv aufgerufen werden kann, brauchst Du zu den vorhandenen Parametern noch einen Winkel.

Dann solltest Du in der Lage sein, das Gebilde in beliebiger Größe an beliebiger Stelle in beliebige Richtung zu malen.

Dann ist erst einmal die Frage, das das Ende ist - das ist vermutlich mit gemaltem Quadrat.

Somit malst Du das Quadrat.
-> dann rufst du das Malen des Dreiecks auf mit N-1.

Das malen des Dreiecks prüft, ob übergebener Parameter N 0 ist -> Abbruch.
Sonst malt es sich selbst (an gegebenen Punkt mit gegebene, Winkel) und ruft an beiden neuen Kanten das Malen des Quadrats auf mit Übergabe N.

Alles, was fehlt, ist nun die Berechnung der jeweiligen Punkte / Winkel. Das malst Du Dir einfach einmal auf um dann entsprechend Rechnen zu können...
 

infos9

Mitglied
Hab den Pythagoras tree noch nicht selbst gezeichnet, müsste ich mir erst Gedanken drum machen wie das geht. Ich übergebe dich mal in kneitzels Hände. :D
 
K

kneitzel

Gast
Du hast doch die Skizze schon selbst gebracht und da siehst Du ja drei Quadrate. Das Basis-Quadrat wurde einfach gerade zur Seite gemalt.

Bei den beiden anderen sind ja etwas gedreht. Und dazu hast Du einen Winkel....

Das ist derzeit alles fest implementiert. Das kannst Du nun etwas zerlegen und universeller machen.

Kannst Du eine Methode drawRect(x1, x2, length, angle) schreiben, mit dem Du dann alle drei Quadrate malst? drawH malt dann von den Quadraten selbst nichts mehr sondern es gibt dann bezüglich der Quadrate nur noch drei Aufrufe von drawRect.
(Und wenn Du alle 4 Seiten des Quadrates malst, dann musst du auch kein Dreieck mehr malen - das wäre noch ein kleiner Tipp...)

Also das Grundquadrat bekommt eine x1, y1, den Winkel 0 und die Größe.

Die Berechnung der Punkte schaust Du Dir einfach einmal bei einem auf einer Ecke stehenden Quadrat an. Dann kannst Du schauen, wie Du die 3 anderen Punkte berechnen kannst. (Wobei Du das ja schon prinzipiell hast, denn Dein Code malt ja wohl schon zwei gedrehte Quadrate :) )
 

Nicolex3

Mitglied
Nein soll kein symmetrischer werden, der markierte Winkel soll immer zufällig gebildet werden, der liegt immer zwischen 30 - 60. Sorry hatte das vergessen zu schreiben.
 

Anhänge

  • Winkel.PNG
    Winkel.PNG
    7 KB · Aufrufe: 24

infos9

Mitglied
Hier einmal ein Grundgerüst... ich weiß allerdings auf die Schnelle nicht, wie der dritte Punkt des Dreiecks berechnet wird... danach müsstest du dann nur noch drawTree rekursiv aufrufen (also du zeichnest einfach nur ein Viereck und ein Dreieck, fertig...):
Java:
import java.awt.Canvas;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Point2D;

import javax.swing.JFrame;

public class Pythagoras_tree extends JFrame {
    private static final long serialVersionUID = 1L;

    public Pythagoras_tree() {
        Canvas can = new Canvas() {
            private static final long serialVersionUID = 1L;

            private void drawTree(Graphics2D g, Point2D.Float p1, Point2D.Float p2, float a, int depth) {
                if (depth == 0)
                    return;
                float l = (float) Math.hypot(p2.x - p1.x, p2.y - p1.y);
                float l2 = l / 2f;
                Point2D.Float p3 = new Point2D.Float(p1.x + l, p1.y - l);
                Point2D.Float p4 = new Point2D.Float(p1.x, p1.y - l);
                g.drawPolygon(new int[] { (int) p1.x, (int) p2.x, (int) p3.x, (int) p4.x },
                              new int[] { (int) p1.y, (int) p2.y, (int) p3.y, (int) p4.y }, 4);

                // Calculate the third point of the triangle...

                // Call draw tree with depth - 1
            }

            @Override
            public void paint(Graphics g) {
                drawTree((Graphics2D) g, new Point2D.Float(250, 500), new Point2D.Float(350, 500), 15, 3);
            }
        };
        this.add(can);
        this.setSize(600, 600);
        this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        this.setVisible(true);
    }

    public static void main(String[] args) {
        new Pythagoras_tree();
    }
}
Prinzipiell findet sich der Code dazu auch auf De Wikipedia. hth
 

infos9

Mitglied
Habs herausgefunden und eine kleine Animation erstellt, sieht nun aus wie Brokkoli.... Die Formel dazu steht hier: https://de.wikipedia.org/wiki/Schnittpunkt#Schnittpunkt_zweier_Geraden
Java:
import java.awt.Canvas;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Point2D;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JFrame;

public class Pythagoras_tree extends JFrame {
    private static final long serialVersionUID = 1L;

    public Pythagoras_tree() {
        Canvas can = new Canvas() {
            private static final long serialVersionUID = 1L;

            private Point2D.Float sp(Point2D.Float a, Point2D.Float b, Point2D.Float c, Point2D.Float d) {
                return new Point2D.Float(
                        ((d.x - c.x) * (b.x * a.y - a.x * b.y) - (b.x - a.x) * (d.x * c.y - c.x * d.y)) / ((d.y - c.y) * (b.x - a.x) - (b.y - a.y) * (d.x - c.x)),
                        ((a.y - b.y) * (d.x * c.y - c.x * d.y) - (c.y - d.y) * (b.x * a.y - a.x * b.y)) / ((d.y - c.y) * (b.x - a.x) - (b.y - a.y) * (d.x - c.x)));
            }

            private Point2D.Float ot(Point2D.Float a, Point2D.Float b, float dir) {
                Point2D.Float c = new Point2D.Float(-(b.y - a.y), (b.x - a.x));
                return new Point2D.Float(a.x + c.x * dir, a.y + c.y * dir);
            }

            private void drawTree(Graphics2D g, Point2D.Float p1, Point2D.Float p2, float a, int depth) {
                if (depth >= System.currentTimeMillis() % 60000 / 5000)
                    return;
                // Calculate the rectangle...
                Point2D.Float p3 = ot(p1, p2, -1);
                Point2D.Float p4 = ot(p2, p1, +1);
                g.drawPolygon(new int[] { (int) p1.x, (int) p2.x, (int) p4.x, (int) p3.x }, new int[] { (int) p1.y, (int) p2.y, (int) p4.y, (int) p3.y }, 4);

                // Calculate the third point of the triangle...
                float w = -(float) Math.atan2(p1.x - p2.x, p1.y - p2.y);
                Point2D.Float p5 = new Point2D.Float(p3.x + 10f * (float) Math.cos(w + Math.toRadians(a)), p3.y + 10f * (float) Math.sin(w + Math.toRadians(a)));
                Point2D.Float p6 = new Point2D.Float(p4.x + 10f * (float) Math.cos(w - Math.toRadians(a)), p4.y + 10f * (float) Math.sin(w - Math.toRadians(a)));
                Point2D.Float p7 = sp(p3, p5, p4, p6);
                g.drawPolygon(new int[] { (int) p3.x, (int) p4.x, (int) p7.x }, new int[] { (int) p3.y, (int) p4.y, (int) p7.y }, 3);

                // Call draw tree with depth + 1
                drawTree(g, p3, p7, a, depth + 1);
                drawTree(g, p7, p4, a, depth + 1);
            }

            @Override
            public void paint(Graphics g) {
                drawTree((Graphics2D) g, new Point2D.Float(250, 500), new Point2D.Float(350, 500), 55, 0);
            }
        };
        this.add(can);
        this.setSize(600, 600);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);

        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                can.repaint();
            }
        }, 1000, 1000);
    }

    public static void main(String[] args) {
        new Pythagoras_tree();
    }
}
 

Neue Themen


Oben