Logo
Distributed Genetic Programming Framework
print print

File org.sfc.gui.Drawer.java

Here you can find all the information about the file org.sfc.gui.Drawer.java. You may explore it here or download it onto your local disk.
/*
 * Copyright (c) 2006 Thomas Weise
 * 
 * E-Mail           : tweise@gmx.de
 * Creation Date    : 2006-02-08 05:19:43
 * Original Filename: org.sfc.gui.Drawer.java
 * Version          : 1.0.1
 * Last modification: 2006-03-07
 *                by: Thomas Weise
 * 
 * License          : GNU LESSER GENERAL PUBLIC LICENSE
 *                    Version 2.1, February 1999
 *                    You should have received a copy of this license along
 *                    with this library; if not, write to the Free Software
 *                    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *                    MA 02111-1307, USA or download the license under
 *                    http://www.gnu.org/copyleft/lesser.html.
 *                    
 * Warranty         : This software is provided "as is" without any
 *                    warranty; without even the implied warranty of
 *                    merchantability or fitness for a particular purpose.
 *                    See the Gnu Lesser General Public License for more
 *                    details.
 */

 
package org.sfc.gui;

import java.awt.Graphics;

import org.sfc.utils.Typesafe;

/**
 * This class comes with some simple helper functions to allow you to draw
 * more complicated things. It allows you, for example, to draw bezier and
 * spline interpolated curves.
 *
 * @author Thomas Weise
 */

public final  class Drawer
  {
/**
 * The start step width of curves.
 */

  private static  final double  START_STEP  = 0.01d;
  
/**
 * The minimum pixel distance for curves.
 */

  private static  final double  MIN_SPACING = 2.0d;
  
/**
 * The maximum pixel distance for curves.
 */

  private static  final double  MAX_SPACING = 4.0d;
  
/**
 * This constructor stops you from instantiating this class.
 */

  private Drawer()
    {
    Typesafe.do_not_call();
    }
   
                                              
  
/**
 * Draw a bezier curve.
 * @param p_g     The graphics context to draw on.
 * @param p_x0    The first x coordinate of the surrounding polygon, which
 *                is the curve's start-point.
 * @param p_y0    The first x coordinate of the surrounding polygon, which
 *                is the curve's start-point.
 * @param p_x1    The second x coordinate of the surrounding polygon.
 * @param p_y1    The second x coordinate of the surrounding polygon.
 * @param p_x2    The third x coordinate of the surrounding polygon.
 * @param p_y2    The third x coordinate of the surrounding polygon.
 * @param p_x3    The forth x coordinate of the surrounding polygon, which
 *                is the curve's end-point.
 * @param p_y3    The forth x coordinate of the surrounding polygon, which
 *                is the curve's end-point.        
 */

  public  static  final void  bezier  (final Graphics p_g,
                                       final int      p_x0,
                                       final int      p_y0,
                                       final int      p_x1,
                                       final int      p_y1,
                                       final int      p_x2,
                                       final int      p_y2,
                                       final int      p_x3,
                                       final int      p_y3)
    {
    final double  l_a, l_b, l_c, l_d, l_e, l_f, l_g, l_h;
          double  l_prev_x, l_prev_y, l_this_x, l_this_y, l_u, l_step;
                    
    l_a       = (-p_x0) + (3.0d*p_x1) - (3.0d*p_x2) + p_x3;
    l_b       = (3.0d*p_x0) - (6.0d*p_x1) + (3.0d*p_x2);
    l_c       = (-3.0d*p_x0) + (3.0d*p_x1);
    l_d       = p_x0;
    l_e       = (-p_y0) + (3.0d*p_y1) - (3.0d*p_y2) + p_y3;
    l_f       = (3.0d*p_y0) - (6.0d*p_y1) + (3.0d*p_y2);
    l_g       = (-3.0d*p_y0) + (3.0d*p_y1);
    l_h       = p_y0;
    l_step    = START_STEP;
  
    l_prev_x  = p_x0;
    l_prev_y  = p_y0;
    l_u       = l_step;

    for(;;)
      {
      l_this_x = ((((((l_a*l_u) + l_b) * l_u) + l_c) * l_u) + l_d);
      l_this_y = ((((((l_e*l_u) + l_f) * l_u) + l_g) * l_u) + l_h);
      
      p_g.drawLine( (int)(l_prev_x + 0.5d), (int)(l_prev_y + 0.5d),
                    (int)(l_this_x + 0.5d), (int)(l_this_y + 0.5d));
      
      if(l_u >= 1.0d) break;
      
      l_prev_x = Math.abs(l_prev_x - l_this_x);
      l_prev_y = Math.abs(l_prev_y - l_this_y);
      
      if( (l_prev_x < MIN_SPACING) && (l_prev_y < MIN_SPACING) )
        {
        l_step *= 1.5d;
        }
      else
        {
        if( (l_prev_x > MAX_SPACING) && (l_prev_y > MAX_SPACING) )
          {
          l_step *= 0.75d;
          }
        }

      l_u += l_step;
      if(l_u > 1.0d) l_u = 1.0d;
      
      l_prev_x = l_this_x;
      l_prev_y = l_this_y;      
      }
    }
  
/**
 * A helper for the spline drawer.
 * @param p_d
 * @param p_i
 * @param p_j
 * @param p_ai
 * @return  double
 */

  private static final  double n(final  double p_d,
                                 final  int    p_i,
                                 final  int    p_j,
                                 final  int[]  p_ai)
    {
    if(p_i == 1)
      {
      return (((p_d > p_ai[p_j + 1]) || (p_d < p_ai[p_j])) ? 0.0d : 1.0d);
      }
      
    if(p_ai[(p_j + p_i) - 1] == p_ai[p_j])
      {
      return ((p_ai[p_j + p_i] - p_d) / (p_ai[p_j + p_i] - p_ai[p_j + 1])) *
              n(p_d, p_i - 1, p_j + 1, p_ai);
      }
      
    if(p_ai[p_j + p_i] == p_ai[p_j + 1])
      {
      return ((p_d - p_ai[p_j]) / (p_ai[(p_j + p_i) - 1] - p_ai[p_j])) *
              n(p_d, p_i - 1, p_j, p_ai);
      }
    
    return (((p_d - p_ai[p_j]) / (p_ai[(p_j + p_i) - 1] - p_ai[p_j])) *
            n(p_d, p_i - 1, p_j, p_ai))
          + (((p_ai[p_j + p_i] - p_d) / (p_ai[p_j + p_i] - p_ai[p_j + 1])) *
              n(p_d, p_i - 1, p_j + 1, p_ai));
    }
  
/**
 * Draws a line with the specified start width and the specified end width.
 * @param p_g           The graphics context to draw on.
 * @param p_x1          The start x coordinate.
 * @param p_y1          The start y coordinate.
 * @param p_x2          The start x coordinate.
 * @param p_y2          The start y coordinate.
 * @param p_start_width The starting line width.
 * @param p_end_width   The ending line width.
 */

  public  static  final void  line  (final Graphics p_g,
                                           double   p_x1,
                                           double   p_y1,
                                           double   p_x2,
                                           double   p_y2,
                                           double   p_start_width,
                                           double   p_end_width)
    {
    fline(p_g, p_x1, p_y1, p_x2, p_y2, p_start_width, p_end_width,
          new int[4], new int[4]);
    }
  
// TODO: The fline-methods are very, very crude. Try to find a better
//       method of creating lines with changing sizes!
  
/**
 * Draws a line with the specified start width and the specified end width.
 * @param p_g           The graphics context to draw on.
 * @param p_x1          The start x coordinate.
 * @param p_y1          The start y coordinate.
 * @param p_x2          The start x coordinate.
 * @param p_y2          The start y coordinate.
 * @param p_start_width The starting line width.
 * @param p_end_width   The ending line width.
 * @param p_x           An array of integer, at least 4 items long.
 * @param p_y           Another array of integer, at least 4 items long.
 */

  private static  final void  fline (final Graphics p_g,
                                           double   p_x1,
                                           double   p_y1,
                                           double   p_x2,
                                           double   p_y2,
                                           double   p_start_width,
                                           double   p_end_width,
                                     final int[]    p_x,
                                     final int[]    p_y)
    {
    double  l_vx, l_vy, l_vb;
    
    l_vx  = (p_y1 - p_y2);
    l_vy  = (p_x2 - p_x1);
        
    l_vb  = 0.5d / Math.sqrt( (l_vx*l_vx) + (l_vy*l_vy) );
    l_vx *= l_vb;
    l_vy *= l_vb;
    
    p_x1 += 0.5d;
    p_y1 += 0.5d;
    p_x2 += 0.5d;
    p_y2 += 0.5d;
          
    p_x[0] = (int) ( p_x1 + (p_start_width * l_vx) );
    p_y[0] = (int) ( p_y1 + (p_start_width * l_vy) );    
    
    p_x[1] = (int) ( p_x2 + (p_end_width * l_vx) );
    p_y[1] = (int) ( p_y2 + (p_end_width * l_vy) );
    
    p_x[2] = (int) ( p_x2 - (p_end_width * l_vx) );
    p_y[2] = (int) ( p_y2 - (p_end_width * l_vy) );    
    
    p_x[3] = (int) ( p_x1 - (p_start_width * l_vx) );
    p_y[3] = (int) ( p_y1 - (p_start_width * l_vy) );
    
    
    
    p_g.fillPolygon(p_x, p_y, 4);
    }
  
/**
 * Draws a line with the specified start width and the specified end width.
 * @param p_g           The graphics context to draw on.
 * @param p_x1          The start x coordinate.
 * @param p_y1          The start y coordinate.
 * @param p_x2          The start x coordinate.
 * @param p_y2          The start y coordinate.
 * @param p_start_width The starting line width.
 * @param p_end_width   The ending line width.
 * @param p_x           An array of integer, at least 6 items long.
 * @param p_y           Another array of integer, at least 6 items long.
 */

  private static  final void  fline_iter(final Graphics p_g,
                                               double   p_x1,
                                               double   p_y1,
                                               double   p_x2,
                                               double   p_y2,
                                               double   p_start_width,
                                               double   p_end_width,                                               
                                         final int[]    p_x,
                                         final int[]    p_y)
    {
    double  l_vx, l_vy, l_vb;
    
    if( (p_x1 == p_x2) && (p_y1 == p_y2)) return;
    
    l_vx  = (p_y1 - p_y2);
    l_vy  = (p_x2 - p_x1);
        
    l_vb  = 0.5d / Math.sqrt( (l_vx*l_vx) + (l_vy*l_vy) );
    l_vx *= l_vb;
    l_vy *= l_vb;
    
    p_x1 += 0.5d;
    p_y1 += 0.5d;
    p_x2 += 0.5d;
    p_y2 += 0.5d;
    
    p_x[0] = p_x[2];
    p_x[5] = p_x[3];
    p_y[0] = p_y[2];
    p_y[5] = p_y[3];
          
    p_x[1] = (int) ( p_x1 + (p_start_width * l_vx) );
    p_y[1] = (int) ( p_y1 + (p_start_width * l_vy) );    
    
    p_x[2] = (int) ( p_x2 + (p_end_width * l_vx) );
    p_y[2] = (int) ( p_y2 + (p_end_width * l_vy) );
    
    p_x[3] = (int) ( p_x2 - (p_end_width * l_vx) );
    p_y[3] = (int) ( p_y2 - (p_end_width * l_vy) );
    
    p_x[4] = (int) ( p_x1 - (p_start_width * l_vx) );
    p_y[4] = (int) ( p_y1 - (p_start_width * l_vy) );
    
    p_g.fillPolygon(p_x, p_y, 6);
    }
  
/**
 * Draw a spline curve which interpolates between some points.
 * @param p_g     The graphics context to draw on.
 * @param p_x     The x-coordinates to use.
 * @param p_y     The y-coordinates to use.
 * @param p_m     The mediation factor: 1 means we draw a straight
 *                polygonal line, 2 means a curve, 3 means an even 
 *                smoother curver and so on.
 */

  public  static  final void  spline  (final Graphics p_g,
                                       final int[]    p_x,
                                       final int[]    p_y,
                                       final int      p_m)
    {
    final int     l_num;
          int     l_r, l_i, l_j;
    final int[]   l_t_array ;
          double  l_x, l_y, l_d, l_d1, l_d2, l_d3, l_d4, l_nvalue, l_step;
    final double  l_max;
        
    l_num     = (p_x.length-1);
    l_t_array = new int[p_m + l_num + 1];
    
    for(l_i = 0; l_i <= (l_num + p_m); l_i++)
      {
      if(l_i < p_m)
        {
        l_t_array[l_i] = 0;
        }
      else
        {
        if( (l_i >= p_m) && (l_i <= l_num) )
          {
          l_t_array[l_i] = (l_i - p_m) + 1;
          }        
        else
          {
          if(l_i > l_num)
            {
            l_t_array[l_i] = (l_num - p_m) + 2;
            }
          }
        }
      }
    
    l_d4   = 0.0d;
    l_r    = 0;    
    l_x    = p_x[0];
    l_y    = p_y[0];
    l_d    = l_x;
    l_d1   = l_y;
    l_step = START_STEP;
    l_max  = l_t_array[l_num + p_m];
    
    for(;;)
      {
      l_d2 = 0.0d;
      l_d3 = 0.0d;
      
      for(l_i = 0; l_i <= l_num; l_i++)
        {
        if((l_d4 >= l_t_array[l_i]) && (l_d4 <= l_t_array[l_i + 1]))
          {
          l_r = l_i;
          }
        }

      for(l_j = Math.max(0, (l_r - p_m) + 1); l_j <= l_r; l_j++)
        {
        l_nvalue = n(l_d4, p_m, l_j, l_t_array);
        l_x = p_x[l_j];
        l_y = p_y[l_j];
        l_d2 += (l_nvalue * l_x);
        l_d3 += (l_nvalue * l_y);
        }

      p_g.drawLine((int)(l_d + 0.5d), (int)(l_d1 + 0.5d),
                   (int)(l_d2 + 0.5d), (int)(l_d3 + 0.5d));
      
      if(l_d4 >= l_max) break;
      
      l_d  = Math.abs( l_d - l_d2);
      l_d1 = Math.abs(l_d1 - l_d3);
      
      if( (l_d < MIN_SPACING) && (l_d1 < MIN_SPACING) )
        {
        l_step *= 1.5d;
        }
      else
        {
        if( (l_d > MAX_SPACING) && (l_d1 > MAX_SPACING) )
          {
          l_step *= 0.75d;
          }
        }

      l_d4 += l_step;
      if(l_d4 > l_max) l_d4 = l_max;
      
      l_d  = l_d2;
      l_d1 = l_d3;
      }

    p_g.drawLine((int)(l_d + 0.5d), (int)(l_d1 + 0.5d), p_x[l_num],
                 p_y[l_num]);
    }
  
  
/**
 * Draw a spline curve which interpolates between some points.
 * @param p_g     The graphics context to draw on.
 * @param p_x     The x-coordinates to use.
 * @param p_y     The y-coordinates to use.
 * @param p_m     The mediation factor: 1 means we draw a straight
 *                polygonal line, 2 means a curve, 3 means an even 
 *                smoother curver and so on.
 * @param p_start_width The starting line width.
 * @param p_end_width   The ending line width.
 */

  public  static  final void  spline  (final Graphics p_g,
                                       final int[]    p_x,
                                       final int[]    p_y,
                                       final int      p_m,
                                       final double   p_start_width,
                                       final double   p_end_width)
    {
    final int     l_num;
          int     l_r, l_i, l_j;
    final int[]   l_t_array, l_xx, l_yy ;
          double  l_x, l_y, l_d, l_d1, l_d2, l_d3, l_d4, l_nvalue, l_step,
                  l_est_len, l_len, l_wstep, l_w, l_q1, l_q2, l_ow;
    final double  l_max;
          boolean l_f;
          
    if( (p_end_width <= 1.0d) && (p_start_width <= 1.0d) )
      {
      spline(p_g, p_x, p_y, p_m);
      return;
      }
        
    l_num     = (p_x.length-1);
    l_t_array = new int[p_m + l_num + 1];
    l_xx      = new int[6];
    l_yy      = new int[6];    
    
    for(l_i = 0; l_i <= (l_num + p_m); l_i++)
      {
      if(l_i < p_m)
        {
        l_t_array[l_i] = 0;
        }
      else
        {
        if( (l_i >= p_m) && (l_i <= l_num) )
          {
          l_t_array[l_i] = (l_i - p_m) + 1;
          }        
        else
          {
          if(l_i > l_num)
            {
            l_t_array[l_i] = (l_num - p_m) + 2;
            }
          }
        }
      }
    
    l_est_len = 0.0d;
    
    for(l_i = l_num; l_i > 0; l_i--)
      {
      l_j = (p_x[l_i] - p_x[l_i-1]);
      l_r = (p_y[l_i] - p_y[l_i-1]);
      l_est_len += Math.sqrt( (l_j*l_j) + (l_r*l_r) );
      }
    
    if(p_m > 2) l_est_len = Math.pow(l_est_len, 1.0d - (0.08d / p_m) );
    
    l_d4    = 0.0d;
    l_r     = 0;    
    l_x     = p_x[0];
    l_y     = p_y[0];
    l_d     = l_x;
    l_d1    = l_y;
    l_step  = START_STEP;
    l_max   = l_t_array[l_num + p_m];
    l_len   = 0.0d;
    l_wstep = ((p_end_width - p_start_width) / l_est_len);
    l_ow    = p_start_width;
    l_f     = true;
    
    for(;;)
      {
      l_d2 = 0.0d;
      l_d3 = 0.0d;
      
      for(l_i = 0; l_i <= l_num; l_i++)
        {
        if((l_d4 >= l_t_array[l_i]) && (l_d4 <= l_t_array[l_i + 1]))
          {
          l_r = l_i;
          }
        }

      for(l_j = Math.max(0, (l_r - p_m) + 1); l_j <= l_r; l_j++)
        {
        l_nvalue = n(l_d4, p_m, l_j, l_t_array);
        l_x = p_x[l_j];
        l_y = p_y[l_j];
        l_d2 += (l_nvalue * l_x);
        l_d3 += (l_nvalue * l_y);
        }
      
      l_q1  = Math.abs( l_d - l_d2);
      l_q2  = Math.abs(l_d1 - l_d3);
      l_len = Math.min(l_est_len, l_len +
                       Math.sqrt( (l_q1*l_q1) + (l_q2*l_q2)) );      
      l_w   = p_start_width + (l_wstep * l_len);
            
      if(l_f)
        {
        if( (l_q1 > 0.0d) || (l_q2 > 0.0d) )
          {
          Drawer.fline(p_g, l_d, l_d1, l_d2, l_d3, l_ow, l_w,
                       l_xx, l_yy);
          
          l_xx[3] = l_xx[2];
          l_xx[2] = l_xx[1];
                    
          l_yy[3] = l_yy[2];
          l_yy[2] = l_yy[1];
          
          l_f = false;
          }
        }
      else
        {
        Drawer.fline_iter(p_g, l_d, l_d1, l_d2, l_d3, l_ow, l_w, l_xx, l_yy);                
        }
      
      l_ow = l_w;
      
      if(l_d4 >= l_max) break;
            
      if( (l_q1 < MIN_SPACING) && (l_q2 < MIN_SPACING) )
        {
        l_step *= 1.5d;
        }
      else
        {
        if( (l_q1 > MAX_SPACING) && (l_q2 > MAX_SPACING) )
          {
          l_step *= 0.75d;
          }
        }

      l_d4 += l_step;
      if(l_d4 > l_max) l_d4 = l_max;
      
      l_d  = l_d2;
      l_d1 = l_d3;
      }

    if(l_f)
      {
      Drawer.fline(p_g, p_x[0], p_y[0], p_x[l_num], p_y[l_num],
                   p_start_width, p_end_width, l_xx, l_yy);
      }
    else
      {
      Drawer.fline_iter(p_g, l_d, l_d1, p_x[l_num], p_y[l_num], l_ow,
                       p_end_width, l_xx, l_yy);
      }
    }
  
  

  }

File Information:

file name:Drawer.java
package:org.sfc.gui
qualified name:org.sfc.gui.Drawer.java
file type:Java Source File
download location:download http://dgpf.sourceforge.net/source/org/sfc/gui/Drawer.java
size:18.251 KB (18690 B)
uploaded: 2018-01-07 12:03:36 GMT+0000
last update: 2006-03-07 04:20:35 GMT+0000
last access: 2018-04-26 03:58:19 GMT+0000

statistics online since 2006-01-02.   RSS Feed
Contact us by sending an email to tweise@gmx.de to receive further information, to report errors, or to join our project.
All content on this site (http://dgpf.sourceforge.net/) is LGPL-licensed.
http://dgpf.sourceforge.net/scripts/source/source.php last modified at 2018-01-07 12:03:34 GMT+0000 served at 2018-04-26 03:58:19 GMT+0000.
Valid CSS Valid XHTML 1.1
Valid RSS SourceForge.net Logo