Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 11
  1. #1
    Utente di HTML.it
    Registrato dal
    Dec 2005
    Messaggi
    53

    Intersezione tra due filloval

    Salve ragazzi,
    mi sto scervellando per sapere come posso fare a capire quando due ellissi disegnati con filloval si accavallano, considerando che il disegno di ellissi risulta essere dinamico.

    spero di essere stato chiaro e vi ringrazio anticipatamente per qualsiasi risposta.

    ciao!

  2. #2
    Utente di HTML.it
    Registrato dal
    Aug 2002
    Messaggi
    8,013
    Non è un problema banale, nemmeno con le più performanti classi di java.awt.geom con cui potresti testare se una data ellissi contiene punti di un'area rettangolare (che potrebbe essere il bounding-rect dell'altra ellissi).

    Non ti resta, mi smentiscano gli utilizzatori più spinti delle librerie grafiche di java, che risolverti il sistemino con le equazioni delle due ellissi.
    <´¯)(¯`¤._)(¯`»ANDREA«´¯)(_.¤´¯)(¯`>
    "The answer to your question is: welcome to tomorrow"

  3. #3
    Utente di HTML.it
    Registrato dal
    Dec 2005
    Messaggi
    53
    ti ringrazio per la risposta, ci avevo provato a risolvermi il sistemino..ma dopo pagine e pagine di passaggi mi stava fondendo il cervello.. :master:

  4. #4
    Utente di HTML.it
    Registrato dal
    Nov 2002
    Messaggi
    72
    Il discorso delle collisioni (di questo si tratta ) non è dei più semplici e un buon punto di partenza è stabilire se ti serve una precisione al Pixel (cioè vuoi che venga rilevata la collisione quando un qualsiasi punto della prima ellisse tocca un qualsiasi punto della seconda ellisse ) oppure una inferiore ma decisamente più performante (e decisamente più semplice da implementare ), nel qual caso viene usata la tecnica del Bounding Box (come afferma andrea1979).

    Tale tecnica costruisce un rettangolo sopra ogni ellisse e vengono verificate le collisioni tra i 2 rettangoli con delle banali sottrazioni di coordinate.

    Un'altra tecnica (ottima per cerchi perfetti) consiste nel calcolare la distanza tra 2 cerchi , se questa è inferiore alla somma dei raggi , queste si stanno toccando.

    In ogni caso.

    Ti consiglio di usare la classe Eclipse2D.Double e il metodo draw (o fill) piuttosto che drawOval.

    Studiati questa piccola animazione che ti ho fatto che sfrutta la tecnica del boundin box e le classi del package geom potrebbe essere un buon punto di partenza …


    import java.awt.*;
    import java.awt.geom.Ellipse2D;
    import java.io.*;
    import java.util.*;

    import javax.imageio.*;
    import javax.swing.*;

    class TestEllisse {
    private int inc=0;
    private boolean toccato=false;
    private Ellipse2D.Double e1=new Ellipse2D.Double();
    private Ellipse2D.Double e2=new Ellipse2D.Double();
    private JFrame frame=new JFrame();
    private Pannello pannello=new Pannello();

    public static void main(String[] a){
    TestEllisse t=new TestEllisse();
    }

    public TestEllisse(){
    frame.setSize(700,600);
    frame.getContentPane().add(pannello);
    frame.show();

    }
    class Pannello extends JPanel{

    ThreadAnim anim=new ThreadAnim();
    public Pannello(){
    anim.start();
    }

    public void paintComponent(Graphics g){
    Graphics2D g2=(Graphics2D)g;
    super.paintComponent(g2);
    e1.setFrame(inc,inc,100,200);
    e2.setFrame(300-inc,300-inc,100,200);
    g2.fill(e1);
    g2.fill(e2);
    toccato=e1.intersects(e2.getBounds2D());
    }
    }
    class ThreadAnim extends Thread{
    public void run(){
    while(!toccato){
    try {
    pannello.repaint();
    Thread.sleep(100);
    inc++;
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    JOptionPane.showMessageDialog(null,"Collisione");
    }
    }
    }

    ciao.

  5. #5
    Utente di HTML.it
    Registrato dal
    Dec 2005
    Messaggi
    53
    ti ringrazio per la disponibilità, mi metto a studiare la piccola animazione che mi hai gentilmente postato e ti faccio sapere.

    ciao!

  6. #6
    Utente di HTML.it
    Registrato dal
    Dec 2005
    Messaggi
    53
    ..interessantissimo il tuo codice!

    però il mio problema è proprio di calcolare la precisione del pixel.
    ma perchè mi consigli di non usare il filloval?

    grazie sempre!

  7. #7
    Utente di HTML.it
    Registrato dal
    Nov 2002
    Messaggi
    72
    Rispondo dopo il lungo ponte

    Se la precisione che necessiti è “al pixel” allora la faccenda cambia (e un po’ si complica ).

    Innanzitutto ti ricordo che:

    1. Se gli oggetti che devono collidere sono sferici (o che tendono ad essere sferici) la precisione può anche essere perfetta attraverso la tecnica dei raggi con un risparmio notevole di cicli Clock.
    2. Più gli oggetti che devono collidere sono piccoli più la tecnica del Bounding Box offre una percezione di una maggiore precisione (nella mia animazione la precisione sembra fare schifo per via delle grosse dimensioni degli oggetti ma se li rimpicciolisci hai la sensazione che la precisione aumenti).
    3. La tecnica del Bounding Box ti servirà comunque per cui implementa lo stesso un metodino che rileva la collisione restituendo un valore booleano.

    Entrando più nel vivo la tecnica che conosco io per rilevare una collisione fra 2 oggetti è detta “Matrice di Bit” , qui te la racconto sommariamente ma ti invito a fare una ricerca su internet dove puoi trovare molte informazioni a riguardo.

    Comincia creando 2 matrici di interi delle dimensioni dei 2 oggetti.

    Successivamente grabba tutti i pixel del primo oggetto da analizzare ed effettua il seguente test:se si tratta di un pixel trasparente poni il valore “0” dentro la matrice se si tratta invece di un pixel non trasparente , poni un “1”.

    Fai lo stesso col secondo.

    Al termine avrai 2 matrici piene di “1” e “0”

    A questo punto ogni volta che vorrai testare se vi è collisione fai una and logica (&) fra tutti i punti delle 2 matrici (in cui dovrai considerare ovviamente anche la loro posizione) , non appena ottieni un valore diverso da “0” , avrai ottenuto una collisione.

    Per concludere 2 considerazioni , la prima è che tu hai oggetti disegnati da “draw” e non immagini caricate da cui grabbare i pixel , ma questo non dovrebbe essere un problema , puoi creare una immagine identica e sostituirla alla tua ellisse e lavorare su quella oppure posizionarla sopra e farla muovere in coincidenza di questa.

    La seconda è che hai bisogno di una immagine che gestisca le trasparenze (4 bit -> RGB + ALFA) in quanto devi interrogare il quarto bit per verificare la trasparenza.Io uso spesso le PNG.

    Per concludere , cosa serve la Bounding Box ? Serve perché come noterai questa tecnica consuma cicli clock che è un piacere per cui ti sconsiglio di testare la collisione con la matrice di bit ad ogni evento di rendering (repaint) ma di testarla con la Bounding Box , se l’evento è verificato , fagli testare la collisione col metodo più sensibile.

    Questa risposta è piuttosto lunga e l’ho riassunta come meglio posso sperando di essere stato chiaro ma ti posso garantire che ci vorrebbero 10 pagine per descriverla nel dettaglio e ti informo già da ora che codificarla nasconde un bel po’ di insidie.

    Ciao.

  8. #8
    Utente di HTML.it
    Registrato dal
    Dec 2005
    Messaggi
    53
    ti ringrazio per la pazienza che hai dimostrato, ma nel frattempo ho risolto il problema di collisione tra due ellissi in maniera matematica:

    dato che risolvere il sistema di due ellissi risultava troppo complicato, ho deciso di risolvere un sistema tra un ellisse e la retta che passa tra il centro dei due ellissi.

    in questa maniera mi trovo 2 punti su ogni ellisse (ma a me ne basta uno per ogni ellisse).

    fatto questo, di ogni ellisse mi prendo la distanza tra il suo centro e il suo punto di intersezione calcolato poc'anzi con il sistema (che chiameremo d1 e d2)

    mi calcolo la distanza tra i due centri dell'ellisse (che chiameremo d).

    se d1+d2<d allora i due ellissi non collidono, altrimenti si.

    spero di essere stato chiaro.

    ciao e ancora grazie per l'aiuto!!

    ps.
    complimenti per il tuo metodo che è un'ottimo metodo!..averci pensato prima avrei evitato una serie di calcoli!!

  9. #9
    Utente di HTML.it
    Registrato dal
    Nov 2002
    Messaggi
    72
    Beh , in fondo mi sembra la tecnica dei raggi di cui ti parlavo…è ovvio che per ellissi molto schiacciate o allungate la precisione può crollare (o per figure irregolari), d’altro canto per cerchi perfetti è della massima precisione.

    Ti suggerisco però (a meno che non ti piaccia farti i tutto in casa) di usare metodi e classi già esistenti , per questa tecnica la classe geom ti aiuta tantissimo.

    Guarda questo esempio , come è facile calcolare la distanza senza ricorrere a sistemi di equazioni.

    codice:
    import java.awt.*;
    import java.awt.geom.Ellipse2D;
    import java.awt.geom.Point2D;
    import java.io.*;
    import java.util.*;
    
    import javax.imageio.*;
    import javax.swing.*;
    
    class TestGeom {
    	public final int DIAMETRO=100;
    	private int inc=0;
    	private boolean toccato=false;
    	private Ellipse2D.Double e1=new Ellipse2D.Double();
    	private Ellipse2D.Double e2=new Ellipse2D.Double();
    	private JFrame frame=new JFrame();
    	private Pannello pannello=new Pannello();
    	
    	public static void main(String[] a){
    		TestGeom t=new TestGeom();
    	}
    	
    	public TestGeom(){
    		frame.setSize(700,600);
    		frame.getContentPane().add(pannello);
    		frame.show();
    		
    	}
    	class Pannello extends JPanel{
    		
    		ThreadAnim anim=new ThreadAnim();
    		public Pannello(){
    			anim.start();
    		}
    		
    		public void paintComponent(Graphics g){ 
    			Graphics2D g2=(Graphics2D)g;
    			super.paintComponent(g2);
    			e1.setFrame(inc,inc,DIAMETRO,DIAMETRO);
    			e2.setFrame(300-inc,300-inc,DIAMETRO,DIAMETRO);
    			g2.fill(e1);
    			g2.fill(e2);
    			 
    			double x1 =e1.getCenterX();
    			double y1 =e1.getCenterY();
    			
    			double x2 =e2.getCenterX();
    			double y2 =e2.getCenterY();
    			
    			Point2D.Double  p1=new Point2D.Double(x1,y1);
    			Point2D.Double  p2=new Point2D.Double(x2,y2);
    			double distanza=p1.distance(p2);
    			if(distanza<DIAMETRO){
    				toccato=true;
    			}
                                          
    		}
    	}
    	class ThreadAnim extends Thread{
    		public void run(){
    			while(!toccato){
    				try {
    					pannello.repaint();
    					Thread.sleep(40);
    					inc++;
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    			}
    			JOptionPane.showMessageDialog(null,"Collisione");
    		}
    	}
    }

  10. #10
    Utente di HTML.it
    Registrato dal
    Dec 2005
    Messaggi
    53
    ti ringrazio infinitamente!!

    non hai idea di quanto tu mi abbia aiutato con i tuoi preziosi suggerimenti!!
    grazie ancora!!
    ciao!!

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.