PhysicDrawing.PhysicGraph.java Source code

Java tutorial

Introduction

Here is the source code for PhysicDrawing.PhysicGraph.java

Source

/*
 * SmartBoard - a freehand drawing and simulation in physic2D on the    
 * work of SmartBoard Team.
 * original source remains:
 * 
 * Copyright (c) 2008 SmartBoard http://sourceforge.net/projects/smart-board/
 * 
 * This source is provided under the terms of the BSD License.
 * 
 * Copyright (c) 2008, SmartBoard
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or 
 * without modification, are permitted provided that the following 
 * conditions are met:
 * 
 *  * Redistributions of source code must retain the above 
 *    copyright notice, this list of conditions and the 
 *    following disclaimer.
 *  * Redistributions in binary form must reproduce the above 
 *    copyright notice, this list of conditions and the following 
 *    disclaimer in the documentation and/or other materials provided 
 *    with the distribution.
 *  * Neither the name of the SmartBoard/New Dawn Software nor the names of 
 *    its contributors may be used to endorse or promote products 
 *    derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 
 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 
 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
 * OF SUCH DAMAGE.
 */
package PhysicDrawing;

import java.awt.Color;
import java.awt.GridLayout;
import java.awt.Rectangle;

import javax.swing.JFrame;

import net.phys2d.raw.Body;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

/**
 * A simple demonstration application showing how to create a line chart using data from an
 * {@link XYDataset}.
 *
 */
public class PhysicGraph extends JFrame implements Runnable {

    private static final long serialVersionUID = 1L;

    private XYSeries distX;
    private XYSeries distY; // S - dataset

    private XYSeries velX;
    private XYSeries velY; // V - dataset

    private XYSeries accX;
    private XYSeries accY;// A - dataset

    /**
     * freq to be update the graph. ....
     * freq HIGH >> low plot
     * freq LOW >> often plot
     * always > 0
     */
    private int freq = 2; // (4)
    private int count = 0;
    private long tStart = 0;
    private float xStart = 0;
    private float yStart = 0;

    //private float xBefore = 0;
    //private float yBefore = 0;

    private float vxBefore = 0;
    private float vyBefore = 0;

    private float lastSec = 0;

    //   private float baseDT = 0.015f;   // 0.015

    private long tPause = 0;
    private long tRun = 0;

    private int maxPlotNumber = 40;

    public Body body; // Body that you want to showing the graph

    private boolean start = false; // Check the graph was the first run or not.

    public Thread thread; // for control thread of physic graph

    private int bodyIndex = -1; // For set body index

    /**
     * Creates a new demo.
     *
     * @param title  the frame title.
     */
    public PhysicGraph(String title) {
        //super(title);

        XYDataset dsDisplacement = createDisplacementDataset();
        XYDataset dsVelocity = createVelocityDataset();
        XYDataset dsAcceleration = createAccelerationDataset();

        JFreeChart chartDisplacement = createDisplacementChart(dsDisplacement);
        JFreeChart chartVelocity = createVelocityChart(dsVelocity);
        JFreeChart chartAcceleration = createAccelerationChart(dsAcceleration);

        ChartPanel chartPanelDis = new ChartPanel(chartDisplacement);
        ChartPanel chartPanelVel = new ChartPanel(chartVelocity);
        ChartPanel chartPanelAcc = new ChartPanel(chartAcceleration);

        chartPanelDis.setPreferredSize(new java.awt.Dimension(250, 250));
        chartPanelVel.setPreferredSize(new java.awt.Dimension(250, 250));
        chartPanelAcc.setPreferredSize(new java.awt.Dimension(250, 250));
        //  chartPanelAcc.
        this.setLayout(new GridLayout(1, 3, 3, 3)); // (row , col , hGAP , vGAP)
        this.add(chartPanelDis);
        this.add(chartPanelVel);
        this.add(chartPanelAcc);

        thread = new Thread(this);

    }

    /**
     * Set the body that you want to show the graph
     * @param body
     */
    public void setBody(Body body) {
        this.body = body;
        String s = "X : " + this.body.getPosition().getX() + " , Y : " + this.body.getPosition().getY();
        this.setTitle("Graph Simulation ; Body references >> " + s);
        start = false;
    }

    /**
     * For set body index that was shown in graph
     * @param bodyIndex
     */
    public void setBodyIndex(int bodyIndex) {
        this.bodyIndex = bodyIndex;
    }

    /**
     * Get body index that was show in graph.
     * @return
     */
    public int getBodyIndex() {
        return this.bodyIndex;
    }

    /**
     * Get the body that was on showing the graph
     * @return
     */
    public Body getBody() {
        return this.body;
    }

    /**
     * Creates a sample dataset.
     * 
     * @return a sample dataset.
     */
    private XYDataset createDisplacementDataset() {

        distX = new XYSeries("Sx");
        distY = new XYSeries("Sy");

        XYSeriesCollection dataset = new XYSeriesCollection();
        dataset.addSeries(distX);
        dataset.addSeries(distY);

        return dataset;
    }

    /**
     * Creates a sample dataset.
     * 
     * @return a sample dataset.
     */
    private XYDataset createVelocityDataset() {

        velX = new XYSeries("Vx");
        velY = new XYSeries("Vy");

        XYSeriesCollection dataset = new XYSeriesCollection();
        dataset.addSeries(velX);
        dataset.addSeries(velY);

        return dataset;

    }

    private XYDataset createAccelerationDataset() {

        accX = new XYSeries("Ax");
        accY = new XYSeries("Ay");

        XYSeriesCollection dataset = new XYSeriesCollection();
        dataset.addSeries(accX);
        dataset.addSeries(accY);

        return dataset;

    }

    /**
     * Creates a chart.
     * 
     * @param dataset  the data for the chart.
     * 
     * @return a chart.
     */
    private JFreeChart createDisplacementChart(XYDataset dataset) {

        // create the chart...
        JFreeChart chart = ChartFactory.createXYLineChart("Displacement", // chart title
                "X - Time (s)", // x axis label
                "Y - S (px)", // y axis label
                dataset, // data
                PlotOrientation.VERTICAL, true, // include legend
                true, // tooltips
                true // urls
        );

        // NOW DO SOME OPTIONAL CUSTOMISATION OF THE CHART...
        chart.setBackgroundPaint(Color.white);

        // get a reference to the plot for further customisation...
        XYPlot plot = chart.getXYPlot();
        plot.setBackgroundPaint(Color.lightGray);
        // plot.setAxisOffset(new Spacer(Spacer.ABSOLUTE, 5.0, 5.0, 5.0, 5.0));
        plot.setDomainGridlinePaint(Color.white); // vertical line 
        plot.setRangeGridlinePaint(Color.white); // horizontal line 

        XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
        renderer.setSeriesLinesVisible(0, true); // (index , value)
        renderer.setSeriesLinesVisible(1, true);
        // renderer.setSeriesShapesVisible(1, true);
        // renderer.setSeriesFillPaint(2, Color.black);
        renderer.setSeriesPaint(0, Color.RED, true);
        renderer.setSeriesPaint(1, Color.black, true);
        renderer.setSeriesPaint(2, Color.white, true);
        renderer.setSeriesShape(0, new Rectangle(1, 1));
        renderer.setSeriesShape(1, new Rectangle(1, 1));

        plot.setRenderer(renderer);

        // change the auto tick unit selection to integer units only...
        NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
        rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
        // OPTIONAL CUSTOMISATION COMPLETED.

        return chart;

    }

    /**
     * Creates a chart.
     * 
     * @param dataset  the data for the chart.
     * 
     * @return a chart.
     */
    private JFreeChart createVelocityChart(XYDataset dataset) {

        // create the chart...
        JFreeChart chart = ChartFactory.createXYLineChart("Velocity", // chart title
                "X - Time (s)", // x axis label
                "Y - V (px/s)", // y axis label
                dataset, // data
                PlotOrientation.VERTICAL, true, // include legend
                true, // tooltips
                false // urls
        );

        // NOW DO SOME OPTIONAL CUSTOMISATION OF THE CHART...
        chart.setBackgroundPaint(Color.white);

        // get a reference to the plot for further customisation...
        XYPlot plot = chart.getXYPlot();
        plot.setBackgroundPaint(Color.lightGray);
        // plot.setAxisOffset(new Spacer(Spacer.ABSOLUTE, 5.0, 5.0, 5.0, 5.0));
        plot.setDomainGridlinePaint(Color.white); // vertical line 
        plot.setRangeGridlinePaint(Color.white); // horizontal line 

        XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
        renderer.setSeriesLinesVisible(0, true); // (index , value)
        renderer.setSeriesLinesVisible(1, true);
        // renderer.setSeriesShapesVisible(1, true);
        // renderer.setSeriesFillPaint(2, Color.black);
        renderer.setSeriesPaint(0, Color.RED, true);
        renderer.setSeriesPaint(1, Color.black, true);
        renderer.setSeriesPaint(2, Color.white, true);
        renderer.setSeriesShape(0, new Rectangle(1, 1));
        renderer.setSeriesShape(1, new Rectangle(1, 1));

        plot.setRenderer(renderer);

        // change the auto tick unit selection to integer units only...
        NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
        rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
        // OPTIONAL CUSTOMISATION COMPLETED.

        return chart;

    }

    private JFreeChart createAccelerationChart(XYDataset dataset) {

        // create the chart...
        JFreeChart chart = ChartFactory.createXYLineChart("Acceleration", // chart title
                "X - Time (s)", // x axis label
                "Y - A (px/s^2)", // y axis label
                dataset, // data
                PlotOrientation.VERTICAL, true, // include legend
                true, // tooltips
                false // urls
        );

        // NOW DO SOME OPTIONAL CUSTOMISATION OF THE CHART...
        chart.setBackgroundPaint(Color.white);

        // get a reference to the plot for further customisation...
        XYPlot plot = chart.getXYPlot();
        plot.setBackgroundPaint(Color.lightGray);
        // plot.setAxisOffset(new Spacer(Spacer.ABSOLUTE, 5.0, 5.0, 5.0, 5.0));
        plot.setDomainGridlinePaint(Color.white); // vertical line 
        plot.setRangeGridlinePaint(Color.white); // horizontal line 

        XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
        renderer.setSeriesLinesVisible(0, true); // (index , value)
        renderer.setSeriesLinesVisible(1, true);
        renderer.setSeriesPaint(0, Color.RED, true);
        renderer.setSeriesPaint(1, Color.black, true);
        renderer.setSeriesPaint(2, Color.white, true);
        renderer.setSeriesShape(0, new Rectangle(1, 1));
        renderer.setSeriesShape(1, new Rectangle(1, 1));

        plot.setRenderer(renderer);

        // change the auto tick unit selection to integer units only...
        NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
        rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
        // OPTIONAL CUSTOMISATION COMPLETED.

        return chart;

    }

    // ****************************************************************************
    // * JFREECHART DEVELOPER GUIDE                                               *
    // * The JFreeChart Developer Guide, written by David Gilbert, is available   *
    // * to purchase from Object Refinery Limited:                                *
    // *                                                                          *
    // * http://www.object-refinery.com/jfreechart/guide.html                     *
    // *                                                                          *
    // * Sales are used to provide funding for the JFreeChart project - please    * 
    // * support us so that we can continue developing free software.             *
    // ****************************************************************************

    /**
     * Starting point for the demonstration application.
     *
     * @param args  ignored.
     */
    public static void main(String[] args) {
        //PhysicGraph dd = new PhysicGraph("Test Graph component");
        ///dd.initGUI();
        //dd.setLocation(0, 150);
    }

    public void initGUI() {
        //this.pack();
        //RefineryUtilities.centerFrameOnScreen(this);
        this.setVisible(true);
        thread.start();
        thread.suspend();
    }
    /*
     public void Start()
     {
        thread.start();
     }*/

    public void pause() {
        //   this.freq = Integer.MAX_VALUE;       
        thread.suspend();
        tPause = System.currentTimeMillis();

    }

    public void resume() {
        //this.freq = 4;
        tRun = System.currentTimeMillis();
        /**
         * Set tStart when users have PAUSED the graph.. So the graph will not be shifted
         * 
         *  If it's called when at 1st time.... 
         *     It will do this + tStart = System.currentTimeMillis
         *  If it's called when user PAUSE
         *      It will do this only .. 
         */
        tStart = tStart + (tRun - tPause);
        thread.resume();

    }

    public void updateDisplacementValue(float sx, float sy, float time) {
        if (distX.getItemCount() == this.maxPlotNumber) {
            distX.remove(0);
        }
        if (distY.getItemCount() == this.maxPlotNumber) {
            distY.remove(0);
        }
        distX.add(time, (double) sx);
        distY.add(time, (double) sy);
    }

    public void clearS() {
        distX.clear();
        distY.clear();
        velX.clear();
        velY.clear();
        accX.clear();
        accY.clear();
        //start = false;

    }

    public void updateVelocityValue(float vx, float vy, float time) {
        if (velX.getItemCount() == this.maxPlotNumber) {
            velX.remove(0);
        }
        if (velY.getItemCount() == this.maxPlotNumber) {
            velY.remove(0);
        }
        velX.add(time, (double) vx);
        velY.add(time, (double) vy);
    }

    public void updateAccelerationValue(float ax, float ay, float time) {
        if (accX.getItemCount() == this.maxPlotNumber) {
            accX.remove(0);
        }
        if (accY.getItemCount() == this.maxPlotNumber) {
            accY.remove(0);
        }
        accX.add(time, (double) ax);
        accY.add(time, (double) ay);

    }

    public float getSx() {
        float xUpdate = body.getPosition().getX() - xStart;
        return xUpdate;
    }

    public float getSy() {
        float yUpdate = yStart - body.getPosition().getY();
        return yUpdate;
    }

    /*
     *
        
    public float getVx(float xUpdate, float xBefore, float dt)
    {
       if(dt == 0)
     dt = 3.7f * 0.33f;
           
       float ret = (xUpdate - xBefore) /(3.7f*dt);   
       return ret;
    }
        
    public float getVy(float yUpdate, float yBefore, float dt)
    {      
       if(dt == 0)
     dt = 3.7f * 0.33f;   
           
       float ret =  (yUpdate - yBefore) / (3.7f*dt);
       return ret;
    }
     */
    public float getAx(float vxUpdate, float vxBefore, float dt) {
        if (dt == 0)
            dt = 0.35f;

        float ret = (vxUpdate - vxBefore) / (4.3f * dt); // 4.3
        //   System.out.println("diff vx "+vxUpdate +" " +vxBefore + " "+(vxUpdate - vxBefore));
        return ret;
    }

    public float getAy(float vyUpdate, float vyBefore, float dt) {
        if (dt == 0)
            dt = 0.35f;

        float ret = (vyUpdate - vyBefore) / (4.3f * dt); // 4.3
        return ret;
    }

    /**
     * Run for get the value of the Object for displaying.
     */
    public void run() {
        while (true) {
            try {
                //   System.out.println("pg : "+this.isVisible());   
                if (this.isVisible() == false) {
                    System.out.println("thread stop");

                    thread.stop();
                    thread.destroy();
                    //this.dispose();         
                    //this = null;
                }

                Thread.sleep(160); // 160 , 360   
                if (this.body != null) {
                    // this block will be called when the graph if first initiated
                    if (!start) {
                        /**
                         * For the x,y displacement
                         */
                        xStart = body.getPosition().getX();
                        yStart = body.getPosition().getY();
                        tStart = System.currentTimeMillis();
                        vxBefore = 0;
                        vyBefore = 0;
                        start = true;
                    }

                    if (count % freq == 0) // the frequency to update
                    {
                        float sec = (float) (System.currentTimeMillis() - tStart) / 1000;

                        float xUpdate = getSx();
                        float yUpdate = getSy();
                        // * 1.0795
                        float vxUpdate = body.getVelocity().getX() * 1.0795f;
                        float vyUpdate = body.getVelocity().getY() * 1.0795f;
                        //   System.out.println("dt : "+(sec-lastSec));

                        //float axUpdate = getAx(vxBefore,sec-lastSec);
                        //float ayUpdate = getAy(vyBefore,sec-lastSec);
                        //float axUpdate = (body.getVelocity().getX() - vxStart) / (baseDT * freq);            
                        //float ayUpdate = (body.getVelocity().getY() - vyStart) / (baseDT * freq);
                        //   System.out.println("cc "+(vyUpdate-vyBefore));
                        float axUpdate = getAx(vxUpdate, vxBefore, (sec - lastSec));
                        float ayUpdate = getAy(vyUpdate, vyBefore, (sec - lastSec));

                        updateDisplacementValue(xUpdate, yUpdate, sec);
                        updateVelocityValue(vxUpdate, vyUpdate, sec);
                        updateAccelerationValue(axUpdate, ayUpdate, sec);

                        vxBefore = vxUpdate;
                        vyBefore = vyUpdate;
                        lastSec = sec;

                    }
                    count++;
                }
            }

            catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

/*
 * public void run() 
   {
  while(true)
  {
     try 
     {   
     //   System.out.println("pg : "+this.isVisible());   
        if(this.isVisible() == false)
        {
           System.out.println("thread stop");   
               
           thread.stop();            
           thread.destroy();
           //this.dispose();         
           //this = null;
        }         
            
        Thread.sleep(160);            
        if(this.body != null)
        {
           if(!start)
           {
              xStart   = body.getPosition().getX();
              yStart   = body.getPosition().getY();
              tStart   = System.currentTimeMillis();
              vxStart  = body.getVelocity().getX();
              vyStart  = body.getVelocity().getY();
              start    = true;
           }   
               
           if(count%freq == 0) // the frequency to update
           {
              float sec = (float)(System.currentTimeMillis() - tStart) / 1000;
                  
              float xUpdate = body.getPosition().getX() - xStart;
              float yUpdate = yStart - body.getPosition().getY();      
                  
              float axUpdate = (body.getVelocity().getX() - vxStart) / (baseDT * freq);            
              float ayUpdate = (body.getVelocity().getY() - vyStart) / (baseDT * freq);
               
              updateDisplacementValue(xUpdate,yUpdate,sec);
              updateVelocityValue(body.getVelocity().getX(), body.getVelocity().getY(), sec);
              updateAccelerationValue(axUpdate,ayUpdate,sec);   
                     
              vxStart = body.getVelocity().getX();
              vyStart = body.getVelocity().getY();
                  
              //this.repaint();
           }
           count++;
        }
     } 
         
     catch (InterruptedException e) 
     {
        e.printStackTrace();
     }
  }
   }
 */