Java/2D Graphics GUI/Line

Материал из Java эксперт
Перейти к: навигация, поиск

A line is drawn using two points

<source lang="java"> import java.awt.BasicStroke; import java.awt.Graphics; import java.awt.Graphics2D; import javax.swing.JFrame; import javax.swing.JPanel; public class LinesDashes1 extends JPanel {

 public void paintComponent(Graphics g) {
   super.paintComponent(g);
   Graphics2D g2d = (Graphics2D) g;
   float[] dash1 = { 2f, 0f, 2f };
   g2d.drawLine(20, 40, 250, 40);
   BasicStroke bs1 = new BasicStroke(1, 
       BasicStroke.CAP_BUTT, 
       BasicStroke.JOIN_ROUND, 
       1.0f, 
       dash1,
       2f);
   g2d.setStroke(bs1);
   g2d.drawLine(20, 80, 250, 80);
   }
 public static void main(String[] args) {
   LinesDashes1 lines = new LinesDashes1();
   JFrame frame = new JFrame("Lines");
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   frame.add(lines);
   frame.setSize(280, 270);
   frame.setLocationRelativeTo(null);
   frame.setVisible(true);
 }

}


 </source>   



Dash style line

<source lang="java"> import java.awt.BasicStroke; import java.awt.Graphics; import java.awt.Graphics2D; import javax.swing.JFrame; import javax.swing.JPanel; public class LinesDashes1 extends JPanel {

 public void paintComponent(Graphics g) {
   super.paintComponent(g);
   Graphics2D g2d = (Graphics2D) g;
   float[] dash1 = { 2f, 0f, 2f };
   g2d.drawLine(20, 40, 250, 40);
   BasicStroke bs1 = new BasicStroke(1, 
       BasicStroke.CAP_BUTT, 
       BasicStroke.JOIN_ROUND, 
       1.0f, 
       dash1,
       2f);
   g2d.setStroke(bs1);
   g2d.drawLine(20, 80, 250, 80);
 }
 public static void main(String[] args) {
   LinesDashes1 lines = new LinesDashes1();
   JFrame frame = new JFrame("Lines");
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   frame.add(lines);
   frame.setSize(280, 270);
   frame.setLocationRelativeTo(null);
   frame.setVisible(true);
 }

}


 </source>   



Draw a point: use a drawLine() method

<source lang="java"> import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.util.Random; import javax.swing.JFrame; import javax.swing.JPanel; public class Points extends JPanel {

 public void paintComponent(Graphics g) {
   super.paintComponent(g);
   Graphics2D g2d = (Graphics2D) g;
   g2d.setColor(Color.red);
   for (int i = 0; i <= 100000; i++) {
     Dimension size = getSize();
     int w = size.width ;
     int h = size.height;
     Random r = new Random();
     int x = Math.abs(r.nextInt()) % w;
     int y = Math.abs(r.nextInt()) % h;
     g2d.drawLine(x, y, x, y);
   }
 }
 public static void main(String[] args) {
   Points points = new Points();
   JFrame frame = new JFrame("Points");
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   frame.add(points);
   frame.setSize(250, 200);
   frame.setLocationRelativeTo(null);
   frame.setVisible(true);
 }

}


 </source>   



Draw Dashed

<source lang="java"> /*

   GNU LESSER GENERAL PUBLIC LICENSE
   Copyright (C) 2006 The Lobo Project
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.
   This library is distributed in the hope that it will be useful,
   but 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.
   You should have received a copy of the GNU Lesser General Public
   License along with this library; if not, write to the Free Software
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   Contact info: lobochief@users.sourceforge.net
  • /

import java.awt.*; public class GUITasks {

 public static Frame getTopFrame() {
   Frame[] frames = Frame.getFrames();
   for(int i = 0; i < frames.length; i++) {
     if(frames[i].getFocusOwner() != null) {
       return frames[i];
     }
   }
   if(frames.length > 0) {
     return frames[0];
   }
   return null;
 }
 
 public static void drawDashed(Graphics g, int x1, int y1, int x2, int y2, int dashSize, int gapSize) {
   if(x2 < x1) {
     int temp = x1;
     x1 = x2;
     x2 = temp;
   }
   if(y2 < y1) {
     int temp = y1;
     y1 = y2;
     y2 = temp;
   }
   int totalDash = dashSize + gapSize;
   if(y1 == y2) {
     int virtualStartX = (x1 / totalDash) * totalDash;
     for(int x = virtualStartX; x < x2; x += totalDash) {
       int topX = x + dashSize;
       if(topX > x2) {
         topX = x2;
       }
       int firstX = x;
       if(firstX < x1) {
         firstX = x1;
       }
       if(firstX < topX) {
         g.drawLine(firstX, y1, topX, y1);
       }
     }
   }
   else if(x1 == x2) {
     int virtualStartY = (y1 / totalDash) * totalDash;
     for(int y = virtualStartY; y < y2; y += totalDash) {
       int topY = y + dashSize;
       if(topY > y2) {
         topY = y2;
       }
       int firstY = y;
       if(firstY < y1) {
         firstY = y1;
       }
       if(firstY < topY) {
         g.drawLine(x1, firstY, x1, topY);
       }
     }     
   }
   else {
     // Not supported
     g.drawLine(x1, y1, x2, y2);
   }
 }

}


 </source>   



Drawing a Line using Java 2D Graphics API

<source lang="java"> import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.Line2D; public class Main extends javax.swing.JFrame {

 public Main() {
   setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
   setSize(600, 600);
 }
 public void paint(Graphics g) {
   Graphics2D g2 = (Graphics2D) g;
   Line2D lin = new Line2D.Float(100, 100, 250, 260);
   g2.draw(lin);
 }
 public static void main(String args[]) {
   new Main().setVisible(true);
 }

}


 </source>   



Draw Optimized Line

<source lang="java"> /*

* Copyright (C) 2004 NNL Technology AB
* Visit www.infonode.net for information about InfoNode(R) 
* products and how to contact NNL Technology AB.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
* MA 02111-1307, USA.
*/

// $Id: GraphicsUtil.java,v 1.4 2005/12/04 13:46:04 jesper Exp $

import javax.swing.*; import java.awt.*; /**

* @author johan
*/

public class GraphicsUtil {

 public static void drawOptimizedLine(Graphics g, int x1, int y1, int x2, int y2) {
   if (g.getColor().getAlpha() < 255 && (x1 == x2 || y1 == y2))
     g.fillRect(x1 < x2 ? x1 : x2, y1 < y2 ? y1 : y2, Math.abs(x2 - x1) + 1, Math.abs(y2 - y1) + 1);
   else
     g.drawLine(x1, y1, x2, y2);
 }
 public static Rectangle calculateIntersectionClip(int x, int y, int width, int height, Shape originalClip) {
   Rectangle bounds = originalClip.getBounds();
   SwingUtilities.ruputeIntersection(x, y, width, height, bounds);
   return bounds;
 }

}


 </source>   



Line dashes style 2

<source lang="java"> import java.awt.BasicStroke; import java.awt.Graphics; import java.awt.Graphics2D; import javax.swing.JFrame; import javax.swing.JPanel; public class LinesDashes2 extends JPanel {

 public void paintComponent(Graphics g) {
   super.paintComponent(g);
   Graphics2D g2d = (Graphics2D) g;
   g2d.drawLine(20, 40, 250, 40);
   float[] dash2 = { 1f, 1f, 1f };
   BasicStroke bs2 = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 1.0f, dash2,2f);
   g2d.setStroke(bs2);
   g2d.drawLine(20, 20, 250, 20);
 }
 public static void main(String[] args) {
   LinesDashes2 lines = new LinesDashes2();
   JFrame frame = new JFrame("Lines");
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   frame.add(lines);
   frame.setSize(280, 270);
   frame.setLocationRelativeTo(null);
   frame.setVisible(true);
 }

}


 </source>   



Line Dash Style 4

<source lang="java"> import java.awt.BasicStroke; import java.awt.Graphics; import java.awt.Graphics2D; import javax.swing.JFrame; import javax.swing.JPanel; public class LinesDashes4 extends JPanel {

 public void paintComponent(Graphics g) {
   super.paintComponent(g);
   Graphics2D g2d = (Graphics2D) g;
   
   float[] dash4 = { 4f, 4f, 1f };
   BasicStroke bs4 = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 1.0f, dash4,
       2f);
       
   g2d.setStroke(bs4);
   g2d.drawLine(20, 20, 250, 20);
 }
 public static void main(String[] args) {
   LinesDashes4 lines = new LinesDashes4();
   JFrame frame = new JFrame("Lines");
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   frame.add(lines);
   frame.setSize(280, 270);
   frame.setLocationRelativeTo(null);
   frame.setVisible(true);
 }

}


 </source>   



Line-graph drawable

<source lang="java"> /**

* 
* LibSparkline : a free Java sparkline chart library
* 
*
* Project Info:  http://reporting.pentaho.org/libsparkline/
*
* (C) Copyright 2008, by Larry Ogrodnek, Pentaho Corporation and Contributors.
*
* This library is free software; you can redistribute it and/or modify it under the terms
* of the Apache License 2.0.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the Apache License 2.0 along with this library;
* if not, a online version is available at http://www.apache.org/licenses/
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
* ------------
* LineGraphDrawable.java
* ------------
*/

import java.awt.Color; import java.awt.Graphics2D; import java.awt.geom.Line2D; import java.awt.geom.Rectangle2D; /**

* A very fast and very simple line-graph drawable. This code is based on the
* LineGraph class writen by Larry Ogrodnek but instead of producing a
* low-resolution image, this class writes the content into a Graphics2D
* context.
* 
* @author Thomas Morgner
*/

public class LineGraphDrawable {

 private static final int DEFAULT_SPACING = 2;
 private int spacing;
 private Color color;
 private Color background;
 private Number[] data;
 /**
  * Creates a default bargraph drawable with some sensible default colors and
  * spacings.
  */
 public LineGraphDrawable() {
   this.color = Color.black;
   this.spacing = DEFAULT_SPACING;
 }
 /**
  * Returns the numeric data for the drawable or null, if the drawable has no
  * data.
  * 
  * @return the data.
  */
 public Number[] getData() {
   return data;
 }
 /**
  * Defines the numeric data for the drawable or null, if the drawable has no
  * data.
  * 
  * @param data
  *          the data (can be null).
  */
 public void setData(final Number[] data) {
   this.data = data;
 }
 /**
  * Returns the main color for the bars.
  * 
  * @return the main color for the bars, never null.
  */
 public Color getColor() {
   return color;
 }
 /**
  * Defines the main color for the bars.
  * 
  * @param color
  *          the main color for the bars, never null.
  */
 public void setColor(final Color color) {
   if (color == null) {
     throw new NullPointerException();
   }
   this.color = color;
 }
 /**
  * Returns the color for the background of the graph. This property can be
  * null, in which case the bar will have a transparent background.
  * 
  * @return color for the background or null, if the graph has a transparent
  *         background color.
  */
 public Color getBackground() {
   return background;
 }
 /**
  * Defines the color for the background of the graph. This property can be
  * null, in which case the bar will have a transparent background.
  * 
  * @param background
  *          the background or null, if the graph has a transparent background
  *          color.
  */
 public void setBackground(final Color background) {
   this.background = background;
 }
 /**
  * Returns the spacing between the bars.
  * 
  * @return the spacing between the bars.
  */
 public int getSpacing() {
   return spacing;
 }
 /**
  * Defines the spacing between the bars.
  * 
  * @param spacing
  *          the spacing between the bars.
  */
 public void setSpacing(final int spacing) {
   this.spacing = spacing;
 }
 /**
  * Draws the bar-graph into the given Graphics2D context in the given area.
  * This method will not draw a graph if the data given is null or empty.
  * 
  * @param graphics
  *          the graphics context on which the bargraph should be rendered.
  * @param drawArea
  *          the area on which the bargraph should be drawn.
  */
 public void draw(final Graphics2D graphics, final Rectangle2D drawArea) {
   if (graphics == null) {
     throw new NullPointerException();
   }
   if (drawArea == null) {
     throw new NullPointerException();
   }
   final int height = (int) drawArea.getHeight();
   if (height <= 0) {
     return;
   }
   final Graphics2D g2 = (Graphics2D) graphics.create();
   if (background != null) {
     g2.setPaint(background);
     g2.draw(drawArea);
   }
   if (data == null || data.length == 0) {
     g2.dispose();
     return;
   }
   g2.translate(drawArea.getX(), drawArea.getY());
   float d = getDivisor(data, height);
   final int spacing = getSpacing();
   final int w = (((int) drawArea.getWidth()) - (spacing * (data.length - 1))) / (data.length - 1);
   float min = Float.MAX_VALUE;
   for (int index = 0; index < data.length; index++) {
     Number i = data[index];
     if (i == null) {
       continue;
     }
     final float value = i.floatValue();
     if (value < min) {
       min = value;
     }
   }
   int x = 0;
   int y = -1;
   if (d == 0.0) {
     // special case -- a horizontal straight line
     d = 1.0f;
     y = -height / 2;
   }
   final Line2D.Double line = new Line2D.Double();
   for (int i = 0; i < data.length - 1; i++) {
     final int px1 = x;
     x += (w + spacing);
     final int px2 = x;
     g2.setPaint(color);
     final Number number = data[i];
     final Number nextNumber = data[i + 1];
     if (number == null && nextNumber == null) {
       final float delta = height - ((0 - min) / d);
       line.setLine(px1, y + delta, px2, y + delta);
     } else if (number == null) {
       line.setLine(px1, y + (height - ((0 - min) / d)), px2, y
           + (height - ((nextNumber.floatValue() - min) / d)));
     } else if (nextNumber == null) {
       line.setLine(px1, y + (height - ((number.floatValue() - min) / d)), px2, y
           + (height - ((0 - min) / d)));
     } else {
       line.setLine(px1, y + (height - ((number.floatValue() - min) / d)), px2, y
           + (height - ((nextNumber.floatValue() - min) / d)));
     }
     g2.draw(line);
   }
   g2.dispose();
 }
 /**
  * Computes the scale factor to scale the given numeric data into the target
  * height.
  * 
  * @param data
  *          the numeric data.
  * @param height
  *          the target height of the graph.
  * @return the scale factor.
  */
 public static float getDivisor(final Number[] data, final int height) {
   if (data == null) {
     throw new NullPointerException("Data array must not be null.");
   }
   if (height < 1) {
     throw new IndexOutOfBoundsException("Height must be greater or equal to 1");
   }
   float max = Float.MIN_VALUE;
   float min = Float.MAX_VALUE;
   for (int index = 0; index < data.length; index++) {
     Number i = data[index];
     if (i == null) {
       continue;
     }
     final float numValue = i.floatValue();
     if (numValue < min) {
       min = numValue;
     }
     if (numValue > max) {
       max = numValue;
     }
   }
   if (max <= min) {
     return 1.0f;
   }
   if (height == 1) {
     return 0;
   }
   return (max - min) / (height - 1);
 }

}


 </source>   



Lines Dashes style 3

<source lang="java"> import java.awt.BasicStroke; import java.awt.Graphics; import java.awt.Graphics2D; import javax.swing.JFrame; import javax.swing.JPanel; public class LinesDashes3 extends JPanel {

 public void paintComponent(Graphics g) {
   super.paintComponent(g);
   Graphics2D g2d = (Graphics2D) g;
   
   float[] dash3 = { 4f, 0f, 2f };
   BasicStroke bs3 = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 1.0f, dash3,
       2f);
   
   g2d.setStroke(bs3);
   g2d.drawLine(20, 60, 250, 60);
 }
 public static void main(String[] args) {
   LinesDashes3 lines = new LinesDashes3();
   JFrame frame = new JFrame("Lines");
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   frame.add(lines);
   frame.setSize(280, 270);
   frame.setLocationRelativeTo(null);
   frame.setVisible(true);
 }

}


 </source>   



Line Styles

<source lang="java"> /*

* Copyright (c) 2000 David Flanagan.  All rights reserved.
* This code is from the book Java Examples in a Nutshell, 2nd Edition.
* It is provided AS-IS, WITHOUT ANY WARRANTY either expressed or implied.
* You may study, use, and modify it for any non-commercial purpose.
* You may distribute it non-commercially as long as you retain this notice.
* For a commercial use license, or to purchase the book (recommended),
* visit http://www.davidflanagan.ru/javaexamples2.
*/

import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.Stroke; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.geom.GeneralPath; import javax.swing.JFrame; import javax.swing.JPanel; /** A demonstration of Java2D line styles */ public class LineStyles extends JPanel{

 public String getName() {
   return "LineStyles";
 }
 public int getWidth() {
   return 450;
 }
 public int getHeight() {
   return 180;
 }
 int[] xpoints = new int[] { 0, 50, 100 }; // X coordinates of our shape
 int[] ypoints = new int[] { 75, 0, 75 }; // Y coordinates of our shape
 // Here are three different line styles we will demonstrate
 // They are thick lines with different cap and join styles
 Stroke[] linestyles = new Stroke[] {
     new BasicStroke(25.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL),
     new BasicStroke(25.0f, BasicStroke.CAP_SQUARE,
         BasicStroke.JOIN_MITER),
     new BasicStroke(25.0f, BasicStroke.CAP_ROUND,
         BasicStroke.JOIN_ROUND), };
 // Another line style: a 2 pixel-wide dot-dashed line
 Stroke thindashed = new BasicStroke(2.0f, // line width
     /* cap style */BasicStroke.CAP_BUTT,
     /* join style, miter limit */BasicStroke.JOIN_BEVEL, 1.0f,
     /* the dash pattern */new float[] { 8.0f, 3.0f, 2.0f, 3.0f },
     /* the dash phase */0.0f); /* on 8, off 3, on 2, off 3 */
 // Labels to appear in the diagram, and the font to use to display them.
 Font font = new Font("Helvetica", Font.BOLD, 12);
 String[] capNames = new String[] { "CAP_BUTT", "CAP_SQUARE", "CAP_ROUND" };
 String[] joinNames = new String[] { "JOIN_BEVEL", "JOIN_MITER",
     "JOIN_ROUND" };
 /** This method draws the example figure */
 public void paint(Graphics g1) {
   Graphics2D g = (Graphics2D) g1;
   // Use anti-aliasing to avoid "jaggies" in the lines
   g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
       RenderingHints.VALUE_ANTIALIAS_ON);
   // Define the shape to draw
   GeneralPath shape = new GeneralPath();
   shape.moveTo(xpoints[0], ypoints[0]); // start at point 0
   shape.lineTo(xpoints[1], ypoints[1]); // draw a line to point 1
   shape.lineTo(xpoints[2], ypoints[2]); // and then on to point 2
   // Move the origin to the right and down, creating a margin
   g.translate(20, 40);
   // Now loop, drawing our shape with the three different line styles
   for (int i = 0; i < linestyles.length; i++) {
     g.setColor(Color.gray); // Draw a gray line
     g.setStroke(linestyles[i]); // Select the line style to use
     g.draw(shape); // Draw the shape
     g.setColor(Color.black); // Now use black
     g.setStroke(thindashed); // And the thin dashed line
     g.draw(shape); // And draw the shape again.
     // Highlight the location of the vertexes of the shape
     // This accentuates the cap and join styles we"re demonstrating
     for (int j = 0; j < xpoints.length; j++)
       g.fillRect(xpoints[j] - 2, ypoints[j] - 2, 5, 5);
     g.drawString(capNames[i], 5, 105); // Label the cap style
     g.drawString(joinNames[i], 5, 120); // Label the join style
     g.translate(150, 0); // Move over to the right before looping again
   }
 }
 public static void main(String[] a){
     JFrame f = new JFrame();
     f.addWindowListener(new WindowAdapter() {
     public void windowClosing(WindowEvent e) {
       System.exit(0);
     }
   });
     f.setContentPane(new LineStyles());
     f.setSize(450,200);
     f.setVisible(true);
 }

}



 </source>   



Xsplinefun displays colorful moving splines in a window

<source lang="java"> /**

* Xsplinefun displays colorful moving splines in a window.
* 
* Taken from xsplinefun, Distribution of 02may92, by Jef Poskanzer,
* jef@netcom.ru, jef@well.sf.ca.us
* 
* @copyright (C) 1992 by Jef Poskanzer
* 
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose and without fee is hereby granted, provided
* that the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation. This software is provided "as is" without express or implied
* warranty.
* 
* First step in converting to Java was to junk all the X Windows stuff; in the
* process we lost all the customization (need to re-add with getopt?).
*/

public class XSplineFun {

 public static final int POINTS = 20;
 public static final int DEFAULT_MAX_COLORS = 20;
 /* Spline-fun smarts. */
 static int x[] = new int [POINTS]; 
   static int y[]= new int [POINTS];
        static int  dx[] = new int [POINTS];
               static int dy[]= new int [POINTS];
 static int nred, ngreen, nblue, dred, dgreen, dblue;
 static int color;
 static Color xcolors[] = new Color[DEFAULT_MAX_COLORS];
 public static void main(String[] av) {
   Frame f = new Frame("Spline Fun");
   XSplineFun xf = new XSplineFun();
   xf.init_splines();
   f.add(xf);
   while(true)
     try {
       xf.move_splines();
       Thread.sleep(150);    // msec
     } catch (Exception e) {
       System.out.println(e);
     }
 }
 static void
 init_splines()
 {
   int i;
   /* Initialize points. */
   for ( i = 0; i < POINTS; ++i )
   {
   x[i] = random() % width;
   y[i] = random() % height;
   dx[i] = random() % ( MAX_DELTA * 2 ) - MAX_DELTA;
   if ( dx[i] <= 0 ) --dx[i];
   dy[i] = random() % ( MAX_DELTA * 2 ) - MAX_DELTA;
   if ( dy[i] <= 0 ) --dy[i];
   }
   /* Initalize colors. */
   for ( color = 0; color < ncolors; ++color )
   {
   xcolors[color].red = xcolors[color].green = xcolors[color].blue = 0;
   xcolors[color].pixel = pixels[color];
   xcolors[color].flags = DoRed|DoGreen|DoBlue;
   }
   color = 0;
   nred = ngreen = nblue = 0;
   dred = random() % ( MAX_COLOR_DELTA * 2 ) - MAX_COLOR_DELTA;
   if ( dred <= 0 ) --dred;
   dgreen = random() % ( MAX_COLOR_DELTA * 2 ) - MAX_COLOR_DELTA;
   if ( dgreen <= 0 ) --dgreen;
   dblue = random() % ( MAX_COLOR_DELTA * 2 ) - MAX_COLOR_DELTA;
   if ( dblue <= 0 ) --dblue;
 }
 static void
 rotate_colormap()
 {
   int t, i;
   if ( forwards )
   {
   t = xcolors[0].pixel;
   for ( i = 0; i < ncolors - 1; ++i )
     xcolors[i].pixel = xcolors[i + 1].pixel;
   xcolors[ncolors - 1].pixel = t;
   XStoreColors(display, cmap, xcolors, ncolors );
   }
   else if ( backwards )
   {
   t = xcolors[ncolors - 1].pixel;
   for ( i = ncolors - 1; i > 0; --i )
     xcolors[i].pixel = xcolors[i - 1].pixel;
   xcolors[0].pixel = t;
   XStoreColors(display, cmap, xcolors, ncolors );
   }
 }
 static void
 new_color()
 {
   int t;
   for ( ; ; )
   {
   t = (int) nred + dred;
   if ( t >= 0 && t < 65536 ) break;
   dred = random() % ( MAX_COLOR_DELTA * 2 ) - MAX_COLOR_DELTA;
   if ( dred <= 0 ) --dred;
   }
   xcolors[color].red = nred = t;
   for ( ; ; )
   {
   t = (int) ngreen + dgreen;
   if ( t >= 0 && t < 65536 ) break;
   dgreen = random() % ( MAX_COLOR_DELTA * 2 ) - MAX_COLOR_DELTA;
   if ( dgreen <= 0 ) --dgreen;
   }
   xcolors[color].green = ngreen = t;
   for ( ; ; )
   {
   t = (int) nblue + dblue;
   if ( t >= 0 && t < 65536 ) break;
   dblue = random() % ( MAX_COLOR_DELTA * 2 ) - MAX_COLOR_DELTA;
   if ( dblue <= 0 ) --dblue;
   }
   xcolors[color].blue = nblue = t;
   XStoreColor(display, cmap, &(xcolors[color]) );
   XSetForeground( display, gc, xcolors[color].pixel );
   if ( ++color >= ncolors ) color -= ncolors;
 }
 static void
 move_splines()
 {
   int i, t, px, py, zx, zy, nx, ny;
   /* Rotate colormap if necessary. */
   rotate_colormap();
   /* Choose new color. */
   new_color();
   /* Backwards rotation requires two new colors each loop. */
   if ( backwards )
   new_color();
   /* Move the points. */
   for ( i = 0; i < POINTS; i++ )
   {
   for ( ; ; )
     {
     t = x[i] + dx[i];
     if ( t >= 0 && t < width ) break;
     dx[i] = random() % ( MAX_DELTA * 2 ) - MAX_DELTA;
     if ( dx[i] <= 0 ) --dx[i];
     }
   x[i] = t;
   for ( ; ; )
     {
     t = y[i] + dy[i];
     if ( t >= 0 && t < height ) break;
     dy[i] = random() % ( MAX_DELTA * 2 ) - MAX_DELTA;
     if ( dy[i] <= 0 ) --dy[i];
     }
   y[i] = t;
   }
   /* Draw the figure. */
   px = zx = ( x[0] + x[POINTS-1] ) / 2;
   py = zy = ( y[0] + y[POINTS-1] ) / 2;
   for ( i = 0; i < POINTS-1; ++i )
   {
   nx = ( x[i+1] + x[i] ) / 2;
   ny = ( y[i+1] + y[i] ) / 2;
   XDrawSpline(g, px, py, x[i], y[i], nx, ny );
   px = nx;
   py = ny;
   }
   XDrawSpline(g, px, py, x[POINTS-1], y[POINTS-1], zx, zy );
 }
 /* X spline routine. */
 int abs(x) {
   return x < 0 ? -x : x;
 }
 static void
 XDrawSpline(Graphics g, int x0, y0, x1, y1, x2, y2) {
   register int xa, ya, xb, yb, xc, yc, xp, yp;
   xa = ( x0 + x1 ) / 2;
   ya = ( y0 + y1 ) / 2;
   xc = ( x1 + x2 ) / 2;
   yc = ( y1 + y2 ) / 2;
   xb = ( xa + xc ) / 2;
   yb = ( ya + yc ) / 2;
   xp = ( x0 + xb ) / 2;
   yp = ( y0 + yb ) / 2;
   if ( abs( xa - xp ) + abs( ya - yp ) > SPLINE_THRESH )
   XDrawSpline( display, d, gc, x0, y0, xa, ya, xb, yb );
   else
   XDrawLine( display, d, gc, x0, y0, xb, yb );
   xp = ( x2 + xb ) / 2;
   yp = ( y2 + yb ) / 2;
   if ( abs( xc - xp ) + abs( yc - yp ) > SPLINE_THRESH )
   XDrawSpline( display, d, gc, xb, yb, xc, yc, x2, y2 );
   else
   XDrawLine( display, d, gc, xb, yb, x2, y2 );
 }

}



 </source>