Domanda Tesina Maturità Java, Biomorfi

Stato
Discussione chiusa ad ulteriori risposte.

DonUriello

Utente Bronze
3 Aprile 2016
10
1
0
31
Ultima modifica da un moderatore:
Salve a tutti. Sto scrivendo la mia tesina per la maturità di quest'anno. Sono giunto ad una situazione critica.

Vi spiego brevemente cosa dovrei fare.
Ho preso spunto da un libro di biologia, dove venivano spiegati i biomorfi. Lo scrittore aveva scritto un programma per ricreare artificialmente quelle creature, o meglio figure. Io scrivo questo programma in java. Ora mi sono trovato a non riuscire più ad andare avanti.

Fatto questa breve premessa, vi posto il codice delle mie classi per capire un po meglio (dopo il codice spiego meglio cosa voglio fare):

Classe Finestra

Java:
Codice:
package tesinaesame2016;
import javax.swing.*;
import java.awt.*;

//applet
import java.applet.*;
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
import java.awt.event.*;


public class Finestra extends JFrame{
  
    public Finestra(){
        setTitle("FinestraTesinaEsame");
        //      lar,alt larg=larghezza, alt=altezza
        setSize(600,600);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        Pannello pannello=new Pannello();
        Container sfondo=getContentPane();
        sfondo.add(pannello,"Center");
        //ascolta i click del mouse
        //addMouseListener(new Finestra.AscoltatoreMouse());
    }//Finestra costruttore
  
}//Finestra

Classe Pannello

Java:
package tesinaesame2016;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Pannello extends JPanel{
    private int x,y; // il loro valore viene preso dal click del mouse
    private Catene lista=new Catene();
  
    public Pannello(){
        addMouseListener(new AscoltatoreMouse());
    }
  
    /**
     * La funzione disegna le linee che andranno a creare il biomorfo
     * @param g oggetto Graphics
  
    public void paint (Graphics g){
        super.paintComponent(g);
        //int x=100,y=100;
      
        int secX=x1+0, secY=y1-50;//seconde coordinare per il ramo dritto
      
        int secXsx, secYsx;//calcolo delle coordinata a sinistra
      
        int secXdx, secYdx;//calcolo della coordinata a destra
              
        g.drawLine(x1,y1,secX,secY);
        for(int i=0; i<5; i++){
            for(int k=0; k<5; k++){
                secXdx=secX+50; secYdx=secY-15; //calcolo destra
                secXsx=secX-50; secYsx=secY-15; //calcolo sinistra
                g.drawLine(secX, secY, secXsx, secYsx); //diramazione sinistra
                g.drawLine(secX, secY, secXdx, secYdx); //diramazione sinistra
                secX=secXsx;
                secY=secYsx;
            }//for
            for(int j=0; j<5; j++){
                secX=x1; secY=y1-50;
                secXdx=secX+50; secYdx=secY-15; //calcolo destra
                secXsx=secX-50; secYsx=secY-15; //calcolo sinistra
                secX=secXdx;
                secY=secYdx;
                g.drawLine(secX, secY, secXsx, secYsx); //diramazione sinistra
                g.drawLine(secX, secY, secXdx, secYdx); //diramazione sinistra
              
            }//for
            //secX+=
        }//for
    }//paint
    */
  
    public void primoTratto(Graphics g, Catene lista){
        super.paintComponent(g);
        //lista.inserisciInTesta(x1, y1);
        g.drawString("ciao",x,y);
        //g.drawLine(lista.getTesta().getX(), lista.getTesta().getY(), lista.getTesta().getX()+50, lista.getTesta().getY());
        System.out.println("Primo nodo: "+lista.getTesta());
    }//primoTratto
  
  
    public void rami(Graphics g,Catene listaC){
        //g.drawLine();
    }
  
    /**
     * La funzione disegna le due diramazioni della linea, a destra e a sinistra
     * @param g oggetto Graphics
     * @param x1 prima coordinata da cui parte la linea (valore x)
     * @param y1 prima coordinata da cui parte la linea (valore y)
    public void diramazioni(Graphics g,int x1, int y1){
        g.drawLine(x1, y1, x1-50, y1-50);
        g.drawLine(x1, y1, y1+50, y1-50);
    }//diramaziaoni*/
  
    //--------------------ASCOLTATORE MOUSE------------------------------------
    class AscoltatoreMouse extends MouseAdapter{
        //ascolta i click del mouse
      
        /**
         * La funzione "Ascolta" i click del mouse, e fa partire il disegna dal
         * punto in cui abbiamo cliccato
         * @param e evento mouse
         */
        public void mousePressed(MouseEvent e){
            x=e.getX();
            y=e.getY();
            repaint();
            //JOptionPane.showMessageDialog(null, x1+" "+y1);
        }//mousePressed
    }//AscoltatoreMouse
  
    //------------------------------LISTA--------------------------------------
    public interface Lista{
        void inserisciInTesta(int x, int y);
        void inserisciInCoda(int x, int y);
        /*Nodo cerca(int valore);
        void inserisciDopo(int x, int y, int valore);
        void stampa();*/
    }//Lista
}//Pannello

Classe Catene

Java:
package tesinaesame2016;

public class Catene{

    public class Nodo{
        private int x,y;
        private Nodo successivo;
      
        public Nodo(){
            x=0;
            y=0;
            successivo=null;
        }
      
        public Nodo(int x, int y){
            this.x=x;
            this.y=y;
            successivo=null;
        }
      
        public Nodo(int x, int y, Nodo successivo){
            this.x=x;
            this.y=y;
            this.successivo=successivo;
        }
      
        public int getX(){
            return x;
        }
      
        public int getY(){
            return y;
        }
      
        public void setX(int x){
            this.x=x;
        }
      
        public void setY(int y){
            this.y=y;
        }
      
        public Nodo getSuccessivo(){
            return successivo;
        }
      
        public void setSuccessivo(Nodo successivo){
            this.successivo=successivo;
        }
    }//Nodo
  
    //-----------------------LISTA CONCATENATA---------------------------------
    public class ListaConcatenata implements Pannello.Lista{
        private Nodo testa;
      
        public ListaConcatenata(){
            testa=null;
        }//ListaConcatenata
      
        public void inserisciInTesta(int x, int y){
            Nodo nuovo=new Nodo(x,y);
            if(testa==null)
                testa=nuovo;
            else{
                Nodo succ=testa;
                nuovo.setSuccessivo(succ);
                testa=nuovo;
            }//if
        }//inserisciInTesta
      
        public void inserisciInCoda(int x, int y){
            Nodo nuovo=new Nodo(x,y);
            if(testa==null)
                testa=nuovo;
            else{
                Nodo succ=testa;
                while(succ.getSuccessivo()!=null){
                    succ=succ.getSuccessivo();
                }//while--controllo in testa
                succ.setSuccessivo(nuovo);
            }//if
        }//inserisciInCoda
      
        public Nodo getTesta(){
            return testa;
        }//getTesta
    }//ListaConcatenata
  
}

Classe TesinaEsame2016

Java:
package tesinaesame2016;


public class TesinaEsame2016 {
  
  
    public static void main(String[] args) {
        //instaziazione dell'oggetto finestra
        Finestra f1=new Finestra();
      
        f1.setLocationRelativeTo(null); //centra la finestra all'interno del desktop
      
    }//main
  
}//TesinaEsame2016

Mi spiace dovervi tartassare con tutto questo codice, ma davvero, nemmeno i professori mi sono stati di aiuto.

Allora, vi spiego, io voglio disegnare un albero, detto in parole molto povere, e per questo intendo usare delle linee. Queste linee le disegno con la funzione drawLine(x1,y1,x2,y2), e per gestire queste linee ho intenzione di utilizzare una lista concatenata. Allora, io so l'albero si "allarga" (fa sempre più rami) seguendo una semplice potenza, la potenza di due: lo disegno con le slash e back slash.

HTML:
       \/\/
        \/
         |

Vi mostro cosa sono i biomorfi --> quì.

Non ha importanza se si dovranno sovrapporre nel programma, perché dovranno sovrapporsi. Tralasciando la parte più importante che sarà proprio quella della sovrapposizione. Io non so come gestire la creazione di questo albero.

Spero di essere stato abbastanza chiaro e comprensibile, ma per qualunque domanda (ed insulto per il codice) sono a vostra disposizione. Mi scuso per la poca documentazione del codice, ma ho studiato java un po da autodidatta, e mi piace.

Grazie in anticipo a qualunque aiuto vogliate offrirmi.
love.gif
crying.gif
 
Sei un pazzo scatenato, ho visto tesi di laurea molto più schifose uscire con 95-100 :\
 
Intanto dovresti implementare la geometria vettoriale suoi tuoi oggetti.
La creazione dell'albero diventa piuttosto semplice cosi, con anche le linee fatte diagonalmente piuttosto precise. L'utilizzo del Canvas potrebbe ritornarti utile, dacci un occhiata

Per la gestione dei nodi potresti sfruttare la classe Tree per la gestione degli alberi. Vedi se riesci a trovare qualcosa qua
http://docs.oracle.com/javase/6/docs/api/javax/swing/tree/package-summary.html

Potresti creare il tuo oggetto e creare con la classe Tree di java il tuo albero con i tuoi oggetti.

Se non vuoi perdere tempo a realizzare la geometria utilizza qualche libreria per come questa
http://geosoft.no/graphics/
 
Devi disegnare una cosa di questo tipo?
screen_2016-04-09-20:09:31.png


Se è così, invece di gestire le linee con una lista concatenata, ti conviene creare un binary tree. Un binary tree è qualcosa che o è null o è un valore con figlio destro e figlio sinistro, dove i figli sono anch'essi dei binary tree. Crea un full binary tree (binary tree dove ogni nodo interno ha due figli non null), aggiungi a questa struttura una linea in testa e ottieni quello in figura.
Non ho capito questa cosa del "dovranno sovrapporsi" e non ho ben capito cosa sono i biomorfi e perché sono in relazione con quello che ti ho screenato, magari una volta che lo capisco si scopre che i binary tree non sono la soluzione migliore. Per ora mi sono semplicemente limitato a spiegarti come disegnare la parte che ho capito.

Quello che ti ho screenato l'ho ottenuto in 5 minuti con il drawLine copiando il pannello e la finestra dal tuo codice, non so se ci sia qualcosa di più pratico. Da quanto ho capito quello che ti ha consigliato Singh è per questi alberi.

Il tuo codice l'ho guardato molto poco, però questo genere di cose:
Java:
public class Classe {
    public class Pippo {
        // ...
    }
    public class Pluto {
        // ...
    }
}
Non si fanno (tu l'hai fatto con la classe Catene). Se vuoi raggruppare delle classi Java ti mette a disposizione il meccanismo dei package. Se definisci una classe all'interno di un altra classe, allora probabilmente vuoi dichiarare le classi interne private e sicuramente vuoi aggiungere qualche funzionalità alla classe esterna.
Lo so che ogni tanto vorresti dichiarare due classi dentro lo stesso file per evitare di switchare continuamente tra i files, ma Java lo proibisce. Cercare degli escamotage per bypassare questo meccanismo è una stronzata.
 
La discussione puoi chiuderla tu stesso. Comunque se hai un po' di pazienza di spiegare cosa vuoi fare esattamente e dove ti blocchi, magari riusciamo ad aiutarti.
 
Bon, allora andiamo avanti.

Non si fanno (tu l'hai fatto con la classe Catene). Se vuoi raggruppare delle classi Java ti mette a disposizione il meccanismo dei package.

Cominciamo con il sistemare le classi.
Devo spostare in un altro file anche Ascoltatore Mouse? e l'interfaccia che ho scritto a cosa serve? (premetto che classe Catena, l'ho copiata da un libro).
E Catena come sistemo? Divido Noto da Lista?
 
Andiamo avanti se è quello che vuoi fare e hai veramente intenzione di dedicarti a fare questa cosa. Io non potrò starti dietro 24h/24 e non è detto che riuscirò a darti sempre risposte immediate, non so gli altri. Capisco che se hai più di un impegno e i tempi stretti sia più facile puntare su qualcosa che conosci meglio.

Prima di sistemare le classi vediamo di capire bene cosa vuoi fare, poi ogni volta che hai bisogno di una certa funzionalità scriviamo ciò che serve per implementarla. Per esempio non hai spiegato se e come devi interagire con il mouse, finché non hai una funzionalità da aggiungere al mouse non ha senso avere un mouse listener.

Nel primo post hai detto di voler disegnare un biomorfo, senza spiegare le caratteristiche di questa figura (poco mi importa di cos'è in biologia), poi hai detto di voler disegnare un albero che parte dal basso verso l'alto diramandosi crescendo come le potenze di 2.
Vuoi veramente disegnare un albero (simile a come te l'ho mostrato nello screenshot?) oppure c'è qualcosa di più? Se fosse solo questo allora ti conviene usare un binary tree invece di una linked list, quindi in questo caso non avresti bisogno di catena, nodo, lista, ecc... Ma prima di iniziare a spiegarti come fare preferisco cercare di capire bene cosa stai cercando di fare. Se devi fare qualche bozza di disegno usa paint piuttosto che l'ascii art, almeno si capisce meglio.
Se invece preferisci fare altro, beh... la tesina la devi fare tu ed è giusto che sia tu a scegliere cosa fare.
 
Si capisco, ognuno ha i propri impegni, ovvio. Se puoi e quando puoi aiutarmi ti ringrazio. Comunque passiamo al problema.

Intanto dico cosa voglio fare, poi scrivo quello che ho fatto io nel frattempo:
Voglio creare una finestra, in cui andremo a disegnare questo fantomatico albero. Vi mostro una foto per farvi vedere come dovrebbe uscire, non è necessario sapere cosa sia, quello c'entra con la spiegazione da fare alla commissione. QUI.
Da qui il mouse diventa pressoché inutile, in effetti erano delle prove che facevo prima. Quindi provvedo immediatamente ad eliminare la funzione e relative classi.
Ora arriviamo alla creazione dell'albero. Puntualizzo che esso debba essere disegnato all'interno della finesta. Io ho usato la classe Graphics (che non viene richiamata all'inizio, ma solo all'interno delle funzioni). Con quella classe uso il metodo drawLine(x1,y1,x2,y2).
Detto questo, io ero riuscito a disegnare un inizio di albero, ma non avevo usato la "lista", quindi dovevo solamente fare tanti for. Scomodo.
Ora vi mostro un albero che all'inizio devo avere:
alberoIni.png

Successivamente dovrà avere delle lunghezze casuali dei rami e pure delle angolazioni casuali. Come questo:
alberoFin.png

Io sono che le diramazioni si moltiplicano sempre seguendo una potenza di due, quindi mi risulterebbe facile calcolare il punto di partenza ed il punto di arrivo del segmento, Disegnato quello torno indietro al punto affianco e disegno nuovamente, e così via.

Beh io ora faccio e provo un pò.
Vorrei chiarire fin da subito che non voglio che lo facciate voi per me, ma una buona spiegazione vi prego di scriverla:myeah:. Come detto, non sono nemmeno abilissimo, ma mi piace imparare java.

Detto questo, un grazie a tutti i volenterosi. Per altri chiarimenti, son qua.:lurker:
 

Cose di questo tipo sono accettabili oppure tutti i livelli devono essere alla stessa altezza? Dalle immagini che hai postato mi sembra anche che i due rami che escono da un nodo devono essere simmetrici, è un caso o un requisito? I rami si possono incrociare tra loro, oppure no?

Ora vi mostro un albero che all'inizio devo avere:
Devi mostrare questo per poi passare all'immagine successiva, o ti interessa semplicemente spawnare dei biomorfi senza necessariamente farli "evolvere" da dalla figura che hai mostrato?

Quelli che ti ho screenato li ho ottenuti con delle modifiche banali al codice che avevo scritto in precedenza. Prima di partire con la spiegazione preferisco capire bene cosa c'è da fare, almeno vado diretto al succo cercando di spiegarti come procedere per ottenere una buona soluzione, senza star li a rattoppare di volta in volta.
 
Scusa la mia assenza, ma ho le simulazioni a scuola, e sono davvero una spina nel fianco durante il lavoro della tesina.

Allora ho visto il tuo lavoro e mi sembra carino, ma io volevo usare il mio codice, usando la mia lista e i miei nodi. Miei nel senso "il codice che ho scritto io". Questo per avere anche qualcosa di cui parlare durante l'orale con la commissione. E far vedere che sono capace. Non per discriminare classi scritte da altri, che chiaramente facilitano il lavoro evitando di scriverlo tante volte.

Allora detto questo, mi sono un pò portato avanti, ho sistemato le classi, ora sono come java richiede.
Ti risposto il codice se vuoi:
LISTA
Java:
package tesinaesame2016;

/**
*
* @author 5A
*/
public class Lista /*implements Pannello.Lista*/{
        private Nodo testa;
      
        public Lista(){
            testa=null;
        }//ListaConcatenata
      
        public void inserisciInTesta(int x, int y){
            Nodo nuovo=new Nodo(x,y);
            if(testa==null)
                testa=nuovo;
            else{
                Nodo succ=testa;
                nuovo.setSuccessivo(succ);
                testa=nuovo;
            }//if
        }//inserisciInTesta
      
        public void inserisciInCoda(int x, int y){
            Nodo nuovo=new Nodo(x,y);
            if(testa==null)
                testa=nuovo;
            else{
                Nodo succ=testa;
                while(succ.getSuccessivo()!=null){
                    succ=succ.getSuccessivo();
                }//while--controllo in testa
                succ.setSuccessivo(nuovo);
            }//if
        }//inserisciInCoda
      
        public Nodo getTesta(){
            return testa;
        }//getTesta
      
   }//ListaConcatenata

NODO
Java:
package tesinaesame2016;

/**
*
* @author 5A
*/
public class Nodo{
        private int x,y;
        private Nodo successivo;
      
        public Nodo(){
            x=0;
            y=0;
            successivo=null;
        }
      
        public Nodo(int x, int y){
            this.x=x;
            this.y=y;
            successivo=null;
        }
      
        public Nodo(int x, int y, Nodo successivo){
            this.x=x;
            this.y=y;
            this.successivo=successivo;
        }
      
        public int getX(){
            return x;
        }
      
        public int getY(){
            return y;
        }
      
        public void setX(int x){
            this.x=x;
        }
      
        public void setY(int y){
            this.y=y;
        }
      
        public Nodo getSuccessivo(){
            return successivo;
        }
      
        public void setSuccessivo(Nodo successivo){
            this.successivo=successivo;
        }
    }//Nodo

TESINAESAME2016
Java:
package tesinaesame2016;


public class TesinaEsame2016 {
  
  
    public static void main(String[] args) {
        //instaziazione dell'oggetto finestra
        Finestra f1=new Finestra();
      
        f1.setLocationRelativeTo(null); //centra la finestra all'interno del desktop
      
    }//main
  
}//TesinaEsame2016

PANNELLO
Sotto stavo provando a fare l'albero, ma devo trovare un buon algoritmo, dopo spiego meglio:
Java:
package tesinaesame2016;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
//import tesinaesame2016;

public class Pannello extends JPanel{
    private int x,y; // il loro valore viene preso dal click del mouse
    private Lista lista=new Lista();
  
    //il metodo deve chiamarsi paint
    public void paint(Graphics g/*, Lista lista*/){
        super.paint(g);
        lista.inserisciInTesta(500, 650);
        for(int i=0, i<50; i++){
            g.drawLine();
          
        }
    }//primoTratto
  
    /*
    public Nodo primoTratto(){
        lista.inserisciInTesta(300,500); //carichiamo il primo punto della lista
        lista.inserisciInTesta(lista.getTesta().getX()+50,lista.getTesta().getY()+150);
        return lista.getTesta();
    }*/
  
}//Pannello

FINESTRA
Java:
package tesinaesame2016;
import javax.swing.*;
import java.awt.*;

//applet
import java.applet.*;
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
import java.awt.event.*;


public class Finestra extends JFrame{
  
    public Finestra(){
        setTitle("FinestraTesinaEsame");
        //      lar ,alt larg=larghezza, alt=altezza
        setSize(1000,700);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        Pannello pannello=new Pannello();
        Container sfondo=getContentPane();
        sfondo.add(pannello,"Center");
        setVisible(true);
      
    }//Finestra costruttore
  
}//Finestra

Allora, adesso spieghiamo il ciclo for incompleto nella classe Pannello. All'interno del ciclo for io voglio gestire la lista. La lista contiene i punti (gli estremi della mia linea che andrà a formare questo magico albero). Io inserisco il primo Nodo ed estraggo x e y, con gli appositi metodi, da mettere nei primi due campi del metodo drawLine(x1,y1,x2,y2). Poi inserisco i secondi, ma i secondi sono calcolati tramite i primi due valori, Finché siamo al priamo ramo, grossi problemi non ci sono, ma quando arrivo alle prime due diramazioni non so come tornare indietro ai primi valori: vi mostro con un disegno, spero si capisca.
P_20160417_174702.jpg


Consigli?
 
Allora ho visto il tuo lavoro e mi sembra carino, ma io volevo usare il mio codice, usando la mia lista e i miei nodi. Miei nel senso "il codice che ho scritto io". Questo per avere anche qualcosa di cui parlare durante l'orale con la commissione. E far vedere che sono capace. Non per discriminare classi scritte da altri, che chiaramente facilitano il lavoro evitando di scriverlo tante volte.
E con questo sono con te al 100%, ed è l'unico motivo per cui non ho postato nemmeno una singola linea di codice. Il lavoro lo devi presentare tu ed è doveroso che sia tu a scriverlo, così che tu conosca perfettamente ogni singola linea di codice.
Quello che ho fatto, l'ho fatto solo per capire bene quali sono i requisiti. Una volta che li ho capiti ti faccio un post dove ti spiego qual'è secondo me il modo migliore per arrivare a quella soluzione, il codice ovviamente dovrai scriverlo tu.

Il problema è che se non capisco bene quello che vuoi ottenere la mia spiegazione potrebbe portarti a dei risultati inconcludenti. È per questa ragione che ti ho screenato quello che ho capito (a partire dalle tue spiegazioni) essere un biomorfo: sto cercando di capire bene quali siano tutti i requisiti, una volta capiti penso ad una buona soluzione e ti faccio un ragionamento che ti aiuterà a trovarla.
Per esempio da quel che ho capito fino ad ora ti consiglierei di usare un binary tree invece che una linked list, ma se c'è qualcosa in più (che non ho capito dalla tua descrizione) il mio consiglio potrebbe rivelarsi sbaglito. È per questo che ti avevo posto quelle domande.
 
Faccio un messaggio corto e vediamo, non sono abilissimo con le parole, risulta più facile con il lavoro davanti e delle immagini... .
Ci provo.

Devo disegnare un albero, questo mi sembra chiaro :). L'albero da principio voglio farlo perfettamente uguale, con le stesse dimensioni dei rami e la stessa angolazione degli stessi. Per questo ti faccio un esempio:
alberoIni.png

Quindi perfettamente uguale in tutto.
Per poi arrivare ad una cosa del genere:
alberoFin.png

Questa dovrebbe diventare un modello di albero completo. Chiaramente avrà molti più ramo. I rami si possono sovrapporre, possono avere lunghezze differenti, angolazioni differenti. ma devono essere sempre simmetrici. Quindi su una riga si devono trovare le stesse dimensioni, angolazioni, ecc.. . Possono anche avere un angolo per cui scendere, quindi possono avere la y negativa.

:bananana:Forse l'ho spiegato bene.

Ora ti spiego la mia idea:

Io dicevo, dato che i rami si espandono secondo la potenza di due (fai riferimento alla foto caricata prima, quella su carta) posso creare una lista in cui salvo tutti i valori degli estremi. Spiegarlo a parole non è facile, ma facendo sempre riferimento alla foto del messaggio prima, devo prendere i vecchi valori. Per esempio, fingiamo di aver disegnato il punto di coordinate x4 y4, quindi abbiamo finito la seconda riga. Adesso dovrei tornare indietro di 2^1 (sinceramente non so bene se sia 2^1 - 1) e prendere i valori x3 e y3. Quà mi blocco...
 
Ok, quindi nel tuo programma dovrai prima mostrare la prima figura e poi farla evolvere (con un'animazione o con qualcosa di simile) alla seconda figura. In entrambe le figure tutti i lati sono lunghi uguali (e già qui, io avevo sbagliato) e tutti i punti da cui parte una diramazione sono alla stessa altezza (anche questo, io non l'avevo fatto).

Partiamo dalla prima figura: tutti i lati sono con la stessa angolazione e tutti i lati interni successivi al quarto livello sovrapposti.
Al posto di usare una lista, io ti consiglio di usare un albero binario. Un albero binario è una struttura dati gerarchica composta da vertici (che sono entità astratte) e dove ogni vertice ha due figli distinguibili (figlio sinistro e figlio destro). Se non sai cos'è un albero binario, inizia a guardare wikipedia, poi se hai qualche domanda falla pure.
Un albero binario si dice completo (full binary tree) quando ogni nodo interno ha entrambi i suoi figli. Ad esempio questo:
diagram1-2.png


È qualcosa di molto simile a quello che vuoi ottenere. Forse è un po' più simile alla tua seconda figura, ma non ha importanza perché basterà far sovrapporre alcuni vertici per ottenere la tua prima figura.
Abbiamo detto che i vertici sono qualcosa di astratto, noi lo dobbiamo concretizzare. Immagina che ogni vertice sia un punto sul piano cartesiano: i due punti sottostanti (che poi collegheremo con una linea) sono i suoi figli e per calcolare la posizione di questi due punti è sufficiente sapere la posizione del punto da cui partono. In altre parole: supponiamo che vuoi disegnare le linee che collegano il punto 1 (sull'immagine che ti ho postato) con i punti 3 e 4, ti è sufficiente sapere le coordinate del punto 1 per calcolare le coordinate del punto 3 e del punto 4.
Con una lista avevi un solo successivo, quindi dovevi magheggiare tra i vari nodi per fare i vari collegamenti, in un binary tree un vertice ha due figli distinti quindi l'implementazione è molto più straightforward.

Come creo un albero binario pieno?
Un albero binario completo è un caso particolare di un albero binario, quindi ti serve qualcosa che gestisca gli alberi binari e ti serve qualcosa che costruisca un albero binario con la caratteristica di essere pieno.
Gli alberi binari possono essere definiti ricorsivamente dicendo:
  1. Null è un albero binario;
  2. Un vertice con figlio sinistro e figlio destro, dove figlio sinistro e figlio destro sono alberi binari, è un albero binario.
Se non ti è chiarissima questa definizione, ti faccio un esempio di come possiamo definire una lista (struttura che immagino tu conosca già bene) allo stesso modo:
  1. Null è una lista;
  2. Un nodo con successivo, dove successivo è una lista, è una lista.
A partire da questo dovresti essere in grado di creare una struttura che mantenga i binary tree, il problema ora è costruirli. A noi non interessa costruire un qualsiasi binary tree, noi vogliamo costruire un binary tree pieno. Possiamo caratterizzare un binary tree pieno dalla sua profondità, per esempio un binary tree di profondità 1 è un vertice con due figli, dove entrambi i figli hanno i lori figli null (eg. quello che ti ho postato ora è un binary tree pieno di profondità 3). La costruzione di un binary tree pieno la possiamo vedere nel modo seguente:
  1. Un binary tree pieno di profondità 0 è un vertice
  2. Un binary tree di profondità n>0 è un vertice dove figlio destro e figlio sinistro sono degli alberi binari pieni di profondità n-1.
Queste due righe ci permettono di creare un full binary tree, ma non sappiamo che valore dare ai vertici (ti ricordo che i nostri vertici sono punti sul piano cartesiano). Conoscendo (x, y) di un vertice, come calcolo (x, y) del suo figlio sinistro e (x, y) del figlio destro? Semplicemente vai in giù (coordinata y) di un valore costante e vai a destra/sinistra sottraendo/sommando un valore costante alla coordinata x del vertice di partenza. Questo ci permette di avere tutti i lati con la stessa angolazione e con la stessa lunghezza.

Come disegno i lati a partire dal full binary tree?
Anche qui possiamo definire la procedura draw in modo ricorsivo, dato un full binary tree:
  1. Se non ha figli, non disegnare una mazza
  2. Se ha figli allora traccia una linea da (x, y) a (x_figlio_sx, y_figlio_sx), traccia una linea da (x, y) a (x_figlio_dx, y_figlio_dx) e disegna l'albero binario figlio_sx e l'albero binario figlio_dx.

Questo dovrebbe bastarti per disegnare la prima figura, sono un pugno di linee di codice, ma devi aver ben chiaro cosa fare. Se non capisci qualcosa chiedi.
 
Direi che gli alberi fanno al caso mio, ma quali sarebbero le classi per gestirlo? Come si chiama nelle API di java, non riesco a trovarla.
 
Direi che gli alberi fanno al caso mio, ma quali sarebbero le classi per gestirlo? Come si chiama nelle API di java, non riesco a trovarla.
La devi creare tu, è per questo che ti ho spiegato come sono definiti. Vai tranquillo che sono un pugno di righe di codice, devi solo capire bene cosa fare.
 
Ultima modifica:
Gli alberi e i grafi sono argomenti che si studiano all'università (te lo dico perché sono al 1^ anno di informatica e di queste cose ce ne in quantità industriale) stai facendo un'ottimo lavoro, non è semplice lo so, ma se la commissione è sveglia, noterà il tuo sforzo. Per la scelta della tipologia di albero più attinente per il tuo scopo, sono d'accordo con st3ve l'albero binario è perfetto.

Personalmente aggiungerei anche dei JButton (ovvero la classe per la creazione di bottoni) dove facendolo comunicare con un ActionListener (più comunemente un'ascoltatore o anche chiamata "orecchia" che tu gli attacchi) reagisca al click del mouse, possibili funzioni collegate a diversi bottoni potrebbero essere le seguenti: aggiunta di un nodo, ricerca di un nodo e la cancellazione (impegnativa).
La grafica deve essere ben curata e soprattutto semplice da comprendere.
Aggiungi anche:
setResizable(false);

p.s. se hai dei dubbi sugli alberi sia a libello teorico che applicativo, inviami pure un messaggio privato. :)
 
Non ci arrivo, è un pò che provo a scrivere questa classe, ma credo mi manchino dei concetti. Non riesco a far comunicare due nodi e mi inceppo sull'inserimento (quando scrivo il metodo). Quando richiamo il metodo inserisci per vedere se funziona mi da errore perchè non ho passato l'oggetto giusto. Ci rinuncio, grazie ragazzi per il vostro aiuto.:)
 
Stato
Discussione chiusa ad ulteriori risposte.