Armi nucleari

Codice animazione fusione

L'animazione 3D della fusione è stato realizzato con Eclipse e con le libreie JOGL.

Main.java

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SpringLayout;
import javax.swing.border.EmptyBorder;

import com.jogamp.newt.event.MouseEvent;
import com.jogamp.newt.event.MouseListener;
import com.jogamp.newt.event.WindowEvent;
import com.jogamp.newt.event.WindowListener;
import com.jogamp.newt.event.WindowUpdateEvent;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLProfile;
import com.jogamp.opengl.util.FPSAnimator;
import java.awt.event.WindowAdapter;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;

public class Main extends JFrame {

	private JPanel contentPane;
	private GLRenderer renderer;
	private GLWindow window;
	private FPSAnimator animator;
	

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					Main frame = new Main();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public Main() {
		addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(java.awt.event.WindowEvent e) {
				window.destroy();
			}
		});
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(0, 150, 296, 167);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		contentPane.setLayout(new BorderLayout(0, 0));
		setContentPane(contentPane);
		
		JButton btnStart = new JButton("Start");
		btnStart.setFocusPainted(false);
		btnStart.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				animator.start();
			}
		});
		contentPane.add(btnStart, BorderLayout.WEST);
		
		JButton btnStop = new JButton("Stop");
		btnStop.setFocusPainted(false);
		btnStop.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				animator.stop();
			}
		});
		contentPane.add(btnStop, BorderLayout.EAST);
		
		JPanel panel = new JPanel();
		contentPane.add(panel, BorderLayout.CENTER);
		SpringLayout sl_panel = new SpringLayout();
		panel.setLayout(sl_panel);
		
		JButton btnReset = new JButton("Reset");
		btnReset.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				renderer.reset();
				window.display();
			}
		});
		sl_panel.putConstraint(SpringLayout.NORTH, btnReset, 10, SpringLayout.NORTH, panel);
		sl_panel.putConstraint(SpringLayout.WEST, btnReset, 10, SpringLayout.WEST, panel);
		panel.add(btnReset);
		
		window = GLWindow.create(new GLCapabilities(GLProfile.getDefault()));
		window.setSize(500, 500);
		
		renderer = new GLRenderer();
		window.addGLEventListener(renderer);
		
		window.setPosition(600, 100);
		window.setVisible(true);
		animator = new FPSAnimator(window, 60, true);
		window.addWindowListener(new WindowListener(){

			@Override
			public void windowResized(WindowEvent e) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void windowMoved(WindowEvent e) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void windowDestroyNotify(WindowEvent e) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void windowDestroyed(WindowEvent e) {
				System.exit(0);				
			}

			@Override
			public void windowGainedFocus(WindowEvent e) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void windowLostFocus(WindowEvent e) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void windowRepaint(WindowUpdateEvent e) {
				// TODO Auto-generated method stub
				
			}
			
		});
		
	}
}

                    

GLRenderer.java

import java.util.ArrayList;

import com.jogamp.opengl.GL;
import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLEventListener;
import com.jogamp.opengl.glu.GLU;
import com.jogamp.opengl.util.gl2.GLUT;

public class GLRenderer implements GLEventListener {
	
	//telecamera
	private int dist = 20, w = 0, h = 0;
	private double rX = -20, rY = -10, rXInc = 0, rYInc = 0;
	private double scale = 1;
	private double xCam = 0, zCam = 0;
	//elementi
	private double r = 0.5;
	public final double DIST_INIZ = 80;
	private double xEl1 = -Math.cos(30 * Math.PI / 180.0) * DIST_INIZ, zEl1 = -Math.sin(30 * Math.PI / 180.0) * DIST_INIZ;
	private double xEl2 = Math.cos(65 * Math.PI / 180.0) * DIST_INIZ, zEl2 = -Math.sin(65 * Math.PI / 180.0) * DIST_INIZ;
	//animazioni
	private double tAnimazione1 = 8, delayAnimazione2 = 1, tAnimazione2 = 5;
	private int frame = 0;
	//tracce
	private ArrayList tracciaEl1 = new ArrayList();
	private ArrayList tracciaEl2 = new ArrayList();
	private ArrayList tracciaP1 = new ArrayList();
	private ArrayList tracciaP2 = new ArrayList();
	
	@Override
	public void init(GLAutoDrawable drawable) {
		GL2 gl = drawable.getGL().getGL2();
		gl.glEnable(GL.GL_DEPTH_TEST);
		gl.glDepthFunc(GL2.GL_LEQUAL);
		gl.glShadeModel(GL2.GL_SMOOTH);
		gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_NICEST);
		
		//luce
		 float[] lAmbiente = new float[]{1, 1, 1, 0};
	     float[] lDiffusa = new float[]{1, 1, 1, 1};
	     float[] lSpeculare = new float[]{0, 0, 0, 0};
	     float[] lPosizione = new float[]{5, 0, 0, 0};

	     gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_DIFFUSE, lDiffusa, 0);
	     gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_SPECULAR, lSpeculare, 0);
	     gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_POSITION, lPosizione, 0);
        
        gl.glEnable(GL2.GL_LIGHT0);
        gl.glEnable(GL2.GL_LIGHTING);
        gl.glEnable(GL2.GL_COLOR_MATERIAL);
	}

	@Override
	public void dispose(GLAutoDrawable drawable) {
		
	}

	@Override
	public void display(GLAutoDrawable drawable) {
		GL2 gl = drawable.getGL().getGL2();
		GLUT glut = new GLUT();
		GLU glu = new GLU();
		
		gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
        gl.glLoadIdentity();
        
        gl.glMatrixMode(GL2.GL_PROJECTION);
        gl.glLoadIdentity();
        //camera su elemento 1 (deuterio)
        if(frame < (2 * tAnimazione1 / 8.0) * 60)
        {
        	xCam = xEl1;
        	zCam = zEl1;
        	rX += (280.0 + 20.0) / ((2 * tAnimazione1 / 8.0) * 60);
        	rY += (0.0 + 10.0) / ((2 * tAnimazione1 / 8.0) * 60);
        }
        //transizione a elemento 2
        if((frame >= (2 * tAnimazione1 / 8.0) * 60) && (frame < (3 * tAnimazione1 / 8.0) * 60))
        {
        	xCam += (xEl2 - xCam) / (((3 *tAnimazione1 / 8.0) * 60) - frame);
        	zCam += (zEl2 - zCam) / (((3 *tAnimazione1 / 8.0) * 60) - frame);
        	rX += (340.0 - 280.0) / ((tAnimazione1 / 8.0) * 60);
        }
        //camera su elemento 2 (trizio)
        if((frame >= (3 * tAnimazione1 / 8.0) * 60) && (frame < (5 * tAnimazione1 / 8.0) * 60))
        {
        	xCam = xEl2;
        	zCam = zEl2;
        	rX += (150.0 + 20.0) / ((2 * tAnimazione1 / 8.0) * 60);
        	rY += (10.0 - 0.0) / ((2 * tAnimazione1 / 8.0) * 60);
        }
        //transizione a scontro
        if((frame >= (5 * tAnimazione1 / 8.0) * 60) && (frame < (6 * tAnimazione1 / 8.0) * 60))
        {
        	xCam += (0 - xCam) / (((6 *tAnimazione1 / 8.0) * 60) - frame);
        	zCam += (0 - zCam) / (((6 *tAnimazione1 / 8.0) * 60) - frame);
        	rX += ((360.0 + 15.0) - 150.0) / ((tAnimazione1 / 8.0) * 60);
        }
        //camera sullo scontro
        if((frame >= (6 * tAnimazione1 / 8.0) * 60) &&(frame < tAnimazione1 * 60))
        {
        	xCam = 0;
        	zCam = 0;
        	scale += (1.2 - 1.0) / ((2 * tAnimazione1 / 8.0) * 60);
        }
        //transizione ai prodotti
        if((frame >= tAnimazione1 * 60) && (frame < (tAnimazione1 + delayAnimazione2) * 60))
        {
        	rX += (195.0 - 15.0) / (delayAnimazione2 * 60);
        	rY += (20.0 - 10.0) / (delayAnimazione2 * 60);
        	scale += (1.0 - 1.2) / (delayAnimazione2 * 60);
        }
        //transizione a prodotto 2 (neutrone)
        if((frame >= (tAnimazione1 + delayAnimazione2) * 60) && (frame < (tAnimazione1 + delayAnimazione2 + (tAnimazione2 / 5.0)) * 60))
        {
        	xCam += (xEl2 - xCam) / (((tAnimazione1 + delayAnimazione2 + (tAnimazione2 / 5.0)) * 60) - frame);
        	zCam += (zEl2 - zCam) / (((tAnimazione1 + delayAnimazione2 + (tAnimazione2 / 5.0)) * 60) - frame);
        	rX += (210.0 - 195.0) / ((tAnimazione2 / 5.0) * 60);
        }
        //camera su prodotto 2
        if((frame >= (tAnimazione1 + delayAnimazione2 + (tAnimazione2 / 5.0)) * 60) && (frame < (tAnimazione1 + delayAnimazione2 + (2 * tAnimazione2 / 5.0)) * 60))
        {
        	xCam = xEl2;
        	zCam = zEl2;
        	rX += (310.0 - 210.0) / ((tAnimazione2 / 5.0) * 60);
        	rY += (5.0 - 20.0) / ((tAnimazione2 / 5.0) * 60);
        }
        //transizione a prodotto 1
        if((frame >= (tAnimazione1 + delayAnimazione2 + (2 * tAnimazione2 / 5.0)) * 60) && (frame < (tAnimazione1 + delayAnimazione2 + (3 * tAnimazione2 / 5.0)) * 60))
        {
        	xCam += (xEl1 - xCam) / (((tAnimazione1 + delayAnimazione2 + (3 *tAnimazione2 / 5.0)) * 60) - frame);
        	zCam += (zEl1 - zCam) / (((tAnimazione1 + delayAnimazione2 + (3 *tAnimazione2 / 5.0)) * 60) - frame);
        	rX += (360.0 - 310.0) / ((tAnimazione2 / 5.0) * 60);
        }
        //camera su prodotto 1 (elio)
        if((frame >= (tAnimazione1 + delayAnimazione2 + (3 * tAnimazione2 / 5.0)) * 60) && (frame < (tAnimazione1 + delayAnimazione2 + (5 * tAnimazione1 / 5.0)) * 60))
        {
        	xCam = xEl1;
        	zCam = zEl1;
        	rX += (300.0 - 0.0) / ((2 * tAnimazione2 / 5.0) * 60);
        	rY += (-10.0 - 5.0) / ((2 * tAnimazione2 / 5.0) * 60);
        }
        
        if(rX >= 360)
        {
        	rX = rX - (Math.floor(rX / 360.0) * 360);
        }
        
        glu.gluPerspective(45, (float) w / h, 1, 200);
        glu.gluLookAt(xCam + (dist * Math.cos((rY + rYInc) * Math.PI / 180.0) * Math.sin((rX + rXInc) * Math.PI / 180.0)), 
            (dist * Math.sin((rY + rYInc) * Math.PI / 180.0)), zCam + (dist * Math.cos((rY + rYInc) * Math.PI / 180.0) * Math.cos((rX + rXInc) * Math.PI / 180.0)), xCam, 0, zCam, 0, 1, 0);
        gl.glMatrixMode(GL2.GL_MODELVIEW);
        gl.glLoadIdentity();
        
        if(frame < tAnimazione1 * 60)
        {
        	//elemento 1 (deuterio)
        	gl.glLoadIdentity();
        	gl.glScaled(scale, scale, scale);
        	gl.glTranslated(xEl1, 0, zEl1);
        	gl.glRotated(60, 0, 1, 0);
        	gl.glRotated(30, 0, 0, 1);
        	gl.glTranslated(-r/2, 0, 0);
        	gl.glColor3d(0.8, 0.8, 0.8);
        	glut.glutSolidSphere(r, 16, 16);
        	gl.glTranslated(r, 0, 0);
        	gl.glColor3d(1, 0, 0);
        	glut.glutSolidSphere(r, 16, 16);
        
        	//elemento 2 (trizio)
        	gl.glLoadIdentity();
        	gl.glScaled(scale, scale, scale);
        	gl.glTranslated(xEl2, 0, zEl2);
        	gl.glRotated(25, 0, 1, 0);
        	gl.glTranslated(r/2, 0, 0);
        	gl.glColor3d(0.8, 0.8, 0.8);
        	glut.glutSolidSphere(r, 16, 16);
        	gl.glTranslated(-r/2 + (r/2 * Math.cos(120.0 / 180.0 * Math.PI)), r/2 * Math.sin(120.0 / 180.0 * Math.PI), 0);
        	gl.glColor3d(1, 0, 0);
        	glut.glutSolidSphere(r, 16, 16);
        	gl.glTranslated(r/2 * Math.cos(120.0 / 180.0 * Math.PI), -2 * r/2 * Math.sin(120.0 / 180.0 * Math.PI), 0);
        	gl.glColor3d(0.8, 0.8, 0.8);
        	glut.glutSolidSphere(r, 16, 16);
        	
        	//tracce elementi iniziali
        	tracciaP1.add(new Point(xEl1, 0 , zEl1));
        	if(tracciaP1.size() >= 40)
        		tracciaP1.remove(0);
        	tracciaP2.add(new Point(xEl2, 0, zEl2));
        	if(tracciaP2.size() >= 40)
        		tracciaP2.remove(0);
        	
        	gl.glLoadIdentity();
        	gl.glScaled(scale, scale, scale);
        	gl.glBegin(GL2.GL_LINES);
        	Point p1, p2;
        	for(int i = tracciaP1.size() - 1; i > 0; i--)
        	{
        		p1 = tracciaP1.get(i);
        		p2 = tracciaP1.get(i - 1);
        		gl.glColor3d(1 - 0.01 * (tracciaP1.size() - 1 - i), 1 - 0.01 * (tracciaP1.size() - 1 - i),1 - 0.01 * (tracciaP1.size() - 1 - i));
        		gl.glVertex3d(p1.getX(), p1.getY(), p1.getZ());
        		gl.glVertex3d(p2.getX(), p2.getY(), p2.getZ());
        	}
        	for(int i = tracciaP2.size() - 1; i > 0; i--)
        	{
        		p1 = tracciaP2.get(i);
        		p2 = tracciaP2.get(i - 1);
        		gl.glColor3d(1 - 0.01 * (tracciaP2.size() - 1 - i), 1 - 0.01 * (tracciaP2.size() - 1 - i),1 - 0.01 * (tracciaP2.size() - 1 - i));
        		gl.glVertex3d(p1.getX(), p1.getY(), p1.getZ());
        		gl.glVertex3d(p2.getX(), p2.getY(), p2.getZ());
        	}
        	gl.glEnd();
        
        	//movimento elementi iniziali
        	xEl1 += Math.cos(30 * Math.PI / 180.0) * DIST_INIZ / (tAnimazione1 * 60);
    		zEl1 += Math.sin(30 * Math.PI / 180.0) * DIST_INIZ / (tAnimazione1 * 60);
    		xEl2 -= Math.cos(65 * Math.PI / 180.0) * DIST_INIZ / (tAnimazione1 * 60);
    		zEl2 += Math.sin(65 * Math.PI / 180.0) * DIST_INIZ / (tAnimazione1 * 60);
        }
        else
        {
        	//flash
        	if(frame == tAnimazione1 * 60){
        		float[] lAmbiente = new float[]{1, 1, 1, 0};
       	     	gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_AMBIENT, lAmbiente, 0);
       	     	xEl1 += 1.2 * r;
       	     	zEl1 += 0;
        	}
        	
        	if(frame == (tAnimazione1 * 60) + 10){
        		float[] lAmbiente = new float[]{0, 0, 0, 0};
       	     	gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_AMBIENT, lAmbiente, 0);
        	}
        	
        	//prodotto 1 (elio)
        	gl.glLoadIdentity();
        	gl.glScaled(scale, scale, scale);
        	gl.glTranslated(xEl1, 0, zEl1);
        	gl.glRotated(45, 0, 1, 0);
        	gl.glTranslated(r/2, -Math.sqrt(7) / (4.0 * Math.sqrt(2)) * r, 0);
        	gl.glColor3d(0.8, 0.8, 0.8);
        	glut.glutSolidSphere(r, 16, 16);
        	gl.glTranslated(-r, 0, 0);
        	gl.glColor3d(1, 0, 0);
        	glut.glutSolidSphere(r, 16, 16);
        	gl.glTranslated(r/2, Math.sqrt(7) / (2.0 * Math.sqrt(2)) * r, r/2);
        	gl.glColor3d(0.8, 0.8, 0.8);
        	glut.glutSolidSphere(r, 16, 16);
        	gl.glTranslated(0, 0, -r);
        	gl.glColor3d(1, 0, 0);
        	glut.glutSolidSphere(r, 16, 16);
        	
        	//prodotto 2 (neutrone)
        	gl.glLoadIdentity();
        	gl.glScaled(scale, scale, scale);
        	gl.glTranslated(xEl2, 0, zEl2);
        	gl.glRotated(5, 0, 1, 0);
        	gl.glColor3d(0.8, 0.8, 0.8);
        	glut.glutSolidSphere(r, 16, 16);
        	
        	//tracce prdotti
        	tracciaP1.add(new Point(xEl1, 0 , zEl1));
        	if(tracciaP1.size() >= 40)
        		tracciaP1.remove(0);
        	tracciaP2.add(new Point(xEl2, 0, zEl2));
        	if(tracciaP2.size() >= 40)
        		tracciaP2.remove(0);
        	
        	gl.glLoadIdentity();
        	gl.glScaled(scale, scale, scale);
        	gl.glBegin(GL2.GL_LINES);
        	Point p1, p2;
        	for(int i = tracciaEl1.size() - 1; i > 0; i--)
        	{
        		p1 = tracciaEl1.get(i);
        		p2 = tracciaEl1.get(i - 1);
        		gl.glColor3d(1 - 0.01 * (tracciaEl1.size() - 1 - i), 1 - 0.01 * (tracciaEl1.size() - 1 - i),1 - 0.01 * (tracciaEl1.size() - 1 - i));
        		gl.glVertex3d(p1.getX(), p1.getY(), p1.getZ());
        		gl.glVertex3d(p2.getX(), p2.getY(), p2.getZ());
        	}
        	if(frame < (tAnimazione1 + delayAnimazione2 + (3 * tAnimazione2 / 5.0)) * 60)
        	{
        		for(int i = tracciaEl2.size() - 1; i > 0; i--)
        		{
        			p1 = tracciaEl2.get(i);
        			p2 = tracciaEl2.get(i - 1);
        			gl.glColor3d(1 - 0.01 * (tracciaEl2.size() - 1 - i), 1 - 0.01 * (tracciaEl2.size() - 1 - i),1 - 0.01 * (tracciaEl2.size() - 1 - i));
        			gl.glVertex3d(p1.getX(), p1.getY(), p1.getZ());
        			gl.glVertex3d(p2.getX(), p2.getY(), p2.getZ());
        		}
        	}
        	//tracce elementi iniziali (per non farli sparire di colpo)
        	if(tracciaEl1.size() >= 1)
        		tracciaEl1.remove(0);
        	if(tracciaEl2.size() >= 1)
        		tracciaEl2.remove(0);
        	for(int i = tracciaP1.size() - 1; i > 0; i--)
        	{
        		p1 = tracciaP1.get(i);
        		p2 = tracciaP1.get(i - 1);
        		gl.glColor3d(1 - 0.01 * (tracciaP1.size() - 1 - i), 1 - 0.01 * (tracciaP1.size() - 1 - i),1 - 0.01 * (tracciaP1.size() - 1 - i));
        		gl.glVertex3d(p1.getX(), p1.getY(), p1.getZ());
        		gl.glVertex3d(p2.getX(), p2.getY(), p2.getZ());
        	}
        	for(int i = tracciaP2.size() - 1; i > 0; i--)
        	{
        		p1 = tracciaP2.get(i);
        		p2 = tracciaP2.get(i - 1);
        		gl.glColor3d(1 - 0.01 * (tracciaP2.size() - 1 - i), 1 - 0.01 * (tracciaP2.size() - 1 - i),1 - 0.01 * (tracciaP2.size() - 1 - i));
        		gl.glVertex3d(p1.getX(), p1.getY(), p1.getZ());
        		gl.glVertex3d(p2.getX(), p2.getY(), p2.getZ());
        	}
        	gl.glEnd();
        	
        	//movimento prodotti
        	if(frame > (tAnimazione1 + delayAnimazione2) * 60)
        	{
        		xEl1 += Math.cos(45 * Math.PI / 180.0) * 20 / (tAnimazione2 * 60);
        		zEl1 += Math.sin(45 * Math.PI / 180.0) * 20 / (tAnimazione2 * 60);
        		xEl2 -= Math.cos(85 * Math.PI / 180.0) * 60 / (tAnimazione2 * 60);
        		zEl2 += Math.sin(85 * Math.PI / 180.0) * 60 / (tAnimazione2 * 60);
        	}
        	
        	if(frame > (tAnimazione1 + delayAnimazione2 + tAnimazione2) * 60){
        		reset();
        	}
        }
        
        frame++;
	}
	
	@Override
	public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) {
		GL2 gl = drawable.getGL().getGL2();
		GLU glu = new GLU();
		this.w = w;
		this.h = h;
        gl.glMatrixMode(GL2.GL_MODELVIEW);
        gl.glLoadIdentity();
	}
	
	public void reset(){
		frame = 0;
		xEl1 = -Math.cos(30 * Math.PI / 180.0) * DIST_INIZ;
		zEl1 = -Math.sin(30 * Math.PI / 180.0) * DIST_INIZ;
		xEl2 = Math.cos(65 * Math.PI / 180.0) * DIST_INIZ;
		zEl2 = -Math.sin(65 * Math.PI / 180.0) * DIST_INIZ;
		rX = -20;
		rY = -10;
		scale = 1;
		tracciaEl1.clear();
		tracciaEl2.clear();
		tracciaP1.clear();
		tracciaP2.clear();
	}

}
                    

Point.java

public class Point {
	double x,  y, z;

	public Point(double x, double y, double z) {
		this.x = x;
		this.y = y;
		this.z = z;
	}

	public double getX() {
		return x;
	}

	public void setX(double x) {
		this.x = x;
	}

	public double getY() {
		return y;
	}

	public void setY(double y) {
		this.y = y;
	}

	public double getZ() {
		return z;
	}

	public void setZ(double z) {
		this.z = z;
	}

}
                    

Torna al sito