/* * (C) 2004 - Geotechnical Software Services * * This code 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 code 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 program; if not, write to the Free * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA. */ import java.awt.*; import java.awt.event.*; import java.text.*; import javax.swing.*; import no.geosoft.cc.geometry.Geometry; import no.geosoft.cc.graphics.*; /** * G demo program. Demonstrates: * * <ul> * <li> A math application * <li> Polyline performance * <li> Geometry generation * </ul> * * @author <a href="mailto:info@geosoft.no">GeoSoft</a> */ public class Demo20 extends JFrame implements ActionListener { private JButton addLevelButton_; private JButton removeLevelButton_; private JLabel nEdgesLabel_; private JLabel lengthLabel_; private JLabel areaLabel_; private KochSnowflake kochSnowflake_; public Demo20() { super ("G Graphics Library - Demo 20"); setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); JPanel controlPanel = new JPanel(); addLevelButton_ = new JButton("+"); addLevelButton_.addActionListener (this); controlPanel.add (addLevelButton_); removeLevelButton_ = new JButton("-"); removeLevelButton_.addActionListener (this); controlPanel.add (removeLevelButton_); nEdgesLabel_ = new JLabel(); controlPanel.add (nEdgesLabel_); lengthLabel_ = new JLabel(); controlPanel.add (lengthLabel_); areaLabel_ = new JLabel(); controlPanel.add (areaLabel_); getContentPane().add (controlPanel, BorderLayout.NORTH); // Create the graphic canvas GWindow window = new GWindow (new Color (255, 255, 255)); getContentPane().add (window.getCanvas(), BorderLayout.CENTER); // Create scene with default viewport and world extent settings GScene scene = new GScene (window); double w0[] = {0.0, 0.0, 0.0}; double w1[] = {1.0, 0.0, 0.0}; double w2[] = {0.0, 1.0, 0.0}; scene.setWorldExtent (w0, w1, w2); // Create the graphics object and add to the scene kochSnowflake_ = new KochSnowflake(); scene.add (kochSnowflake_); pack(); setSize (new Dimension (500, 500)); setVisible (true); window.startInteraction (new ZoomInteraction (scene)); refresh(); } public void actionPerformed (ActionEvent event) { if (event.getSource() == addLevelButton_) kochSnowflake_.addLevel(); else kochSnowflake_.removeLevel(); refresh(); } public void refresh() { nEdgesLabel_.setText ("#edges = " + kochSnowflake_.getNEdges()); DecimalFormat format = new DecimalFormat ("0.00000"); double length = kochSnowflake_.computeLength(); lengthLabel_.setText (" Length = " + format.format (length)); double area = kochSnowflake_.computeArea(); areaLabel_.setText (" Area = " + format.format (area)); kochSnowflake_.refresh(); } /** * Defines the geometry and presentation for the sample * graphic object. */ private class KochSnowflake extends GObject { private GSegment curve_; private double[] geometry_; KochSnowflake() { GStyle style = new GStyle(); style.setForegroundColor (new Color (255, 0, 0)); style.setBackgroundColor (new Color (255, 255, 0)); setStyle (style); curve_ = new GSegment(); geometry_ = new double[] {0.2, 0.2, 0.8, 0.2, 0.5, 0.2 + 0.6 * Math.sin (Math.PI / 3.0), 0.2, 0.2}; addSegment (curve_); } public int getNEdges() { return geometry_.length / 2 - 1; } public double computeLength() { double length = 0; for (int i = 0; i < geometry_.length - 2; i += 2) { length += Geometry.length (geometry_[i+0], geometry_[i+1], geometry_[i+2], geometry_[i+3]); } return length; } public double computeArea() { return Geometry.computePolygonArea (geometry_); } public void addLevel() { int nLegs = geometry_.length / 2 - 1; int nPoints = nLegs * 4 * 2 + 2; double[] geometry = new double[nPoints]; int j = 0; for (int i = 0; i < nLegs*2; i += 2) { geometry[j+0] = geometry_[i+0]; geometry[j+1] = geometry_[i+1]; double[] v0 = Geometry.computePointOnLine (geometry_[i+0], geometry_[i+1], geometry_[i+2], geometry_[i+3], 1.0 / 3.0); geometry[j+2] = v0[0]; geometry[j+3] = v0[1]; double[] v1 = Geometry.computePointOnLine (geometry_[i+0], geometry_[i+1], geometry_[i+2], geometry_[i+3], 2.0 / 3.0); geometry[j+6] = v1[0]; geometry[j+7] = v1[1]; double length = Geometry.length (v0[0], v0[1], v1[0], v1[1]); double dx = geometry_[i+2] - geometry_[i+0]; double dy = geometry_[i+3] - geometry_[i+1]; double l = Math.sqrt (dx * dx + dy * dy); double angle = Math.acos (dx / l); if (dy < 0) angle = 2.0 * Math.PI - angle; angle -= Math.PI / 3.0; geometry[j+4] = geometry[j+2] + length * Math.cos (angle); geometry[j+5] = geometry[j+3] + length * Math.sin (angle); j+= 8; } geometry[geometry.length-2] = geometry[0]; geometry[geometry.length-1] = geometry[1]; geometry_ = geometry; redraw(); } public void removeLevel() { int nLegs = geometry_.length / 2 - 1; if (nLegs == 3) return; int nPoints = nLegs / 4 * 2 + 2; double[] geometry = new double[nPoints]; int j = 0; for (int i = 0; i < geometry.length - 2; i += 2) { geometry[i+0] = geometry_[j+0]; geometry[i+1] = geometry_[j+1]; j += 8; } geometry[geometry.length-2] = geometry[0]; geometry[geometry.length-1] = geometry[1]; geometry_ = geometry; redraw(); } public void draw() { curve_.setGeometryXy (geometry_); } } public static void main (String[] args) { new Demo20(); } }