Java/2D Graphics GUI/Line
Содержание
- 1 A line is drawn using two points
- 2 Dash style line
- 3 Draw a point: use a drawLine() method
- 4 Draw Dashed
- 5 Drawing a Line using Java 2D Graphics API
- 6 Draw Optimized Line
- 7 Line dashes style 2
- 8 Line Dash Style 4
- 9 Line-graph drawable
- 10 Lines Dashes style 3
- 11 Line Styles
- 12 Xsplinefun displays colorful moving splines in a window
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>