From 12ddf37f23cd77903729b3e611ffae10e96ded47 Mon Sep 17 00:00:00 2001 From: Thomas Neidhart Date: Sun, 9 Feb 2014 22:10:04 +0000 Subject: [PATCH] Simplify geometry examples by using piccolo2d. git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1566450 13f79535-47bb-0310-9956-ffa450edef68 --- .../userguide/geometry/ConvexHullExample.java | 151 ---------------- .../geometry/EnclosingBallExample.java | 143 ---------------- .../userguide/geometry/GeometryExample.java | 162 ++++++++++++++++++ src/userguide/pom.xml | 12 +- 4 files changed, 173 insertions(+), 295 deletions(-) delete mode 100644 src/userguide/java/org/apache/commons/math3/userguide/geometry/ConvexHullExample.java delete mode 100644 src/userguide/java/org/apache/commons/math3/userguide/geometry/EnclosingBallExample.java create mode 100644 src/userguide/java/org/apache/commons/math3/userguide/geometry/GeometryExample.java diff --git a/src/userguide/java/org/apache/commons/math3/userguide/geometry/ConvexHullExample.java b/src/userguide/java/org/apache/commons/math3/userguide/geometry/ConvexHullExample.java deleted file mode 100644 index 410605cbe..000000000 --- a/src/userguide/java/org/apache/commons/math3/userguide/geometry/ConvexHullExample.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.commons.math3.userguide.geometry; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.FlowLayout; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.RenderingHints; -import java.awt.geom.Line2D; -import java.awt.geom.Rectangle2D; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import javax.swing.JComponent; - -import org.apache.commons.math3.geometry.euclidean.twod.Vector2D; -import org.apache.commons.math3.geometry.euclidean.twod.hull.ConvexHull2D; -import org.apache.commons.math3.geometry.euclidean.twod.hull.ConvexHullGenerator2D; -import org.apache.commons.math3.geometry.euclidean.twod.hull.MonotoneChain; -import org.apache.commons.math3.random.MersenneTwister; -import org.apache.commons.math3.random.RandomGenerator; -import org.apache.commons.math3.userguide.ExampleUtils; -import org.apache.commons.math3.userguide.ExampleUtils.ExampleFrame; - -/** - * Shows how to generate the convex hull of a point cloud in 2D. - */ -public class ConvexHullExample { - - public static List createRandomPoints(int size) { - RandomGenerator random = new MersenneTwister(); - - // create the cloud container - List points = new ArrayList(size); - // fill the cloud with a random distribution of points - for (int i = 0; i < size; i++) { - points.add(new Vector2D(random.nextDouble() * 2.0 - 1.0, random.nextDouble() * 2.0 - 1.0)); - } - return points; - } - - @SuppressWarnings("serial") - public static class Display extends ExampleFrame { - - public Display() { - setTitle("Commons-Math: Convex Hull example"); - setSize(400, 400); - - setLayout(new FlowLayout()); - - ConvexHullGenerator2D generator = new MonotoneChain(true); - Collection cloud = createRandomPoints(150); - ConvexHull2D hull = generator.generate(cloud); - - add(new Plot(cloud, hull)); - } - } - - @SuppressWarnings("serial") - public static class Plot extends JComponent { - - private static double PAD = 10; - - private Iterable cloud; - private ConvexHull2D hull; - - public Plot(Iterable cloud, ConvexHull2D hull) { - this.cloud = cloud; - this.hull = hull; - } - - @Override - protected void paintComponent(Graphics g) { - super.paintComponent(g); - Graphics2D g2 = (Graphics2D)g; - g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, - RenderingHints.VALUE_ANTIALIAS_ON); - - int w = getWidth(); - int h = getHeight(); - - g2.clearRect(0, 0, w, h); - - g2.setPaint(Color.black); - g2.drawRect(0, 0, w - 1, h - 1); - - for (Vector2D point : cloud) { - drawPoint(g2, point, w, h); - } - - g.setColor(Color.RED); - Vector2D firstPoint = hull.getVertices()[0]; - Vector2D lastPoint = null; - for (Vector2D point : hull.getVertices()) { - drawPoint(g2, point, w, h); - if (lastPoint != null) { - drawLine(g2, lastPoint, point, w, h); - } - lastPoint = point; - } - - drawLine(g2, lastPoint, firstPoint, w, h); - } - - private void drawPoint(Graphics2D g2, Vector2D point, int width, int height) { - Vector2D p = transform(point, width, height); - double[] arr = p.toArray(); - g2.draw(new Rectangle2D.Double(arr[0] - 1, arr[1] - 1, 2, 2)); - } - - public void drawLine(Graphics2D g2, Vector2D point1, Vector2D point2, int width, int height) { - Vector2D p1 = transform(point1, width, height); - double[] arr1 = p1.toArray(); - Vector2D p2 = transform(point2, width, height); - double[] arr2 = p2.toArray(); - g2.draw(new Line2D.Double(arr1[0], arr1[1], arr2[0], arr2[1])); - } - - @Override - public Dimension getPreferredSize() { - return new Dimension(300, 300); - } - - private Vector2D transform(Vector2D point, int width, int height) { - double[] arr = point.toArray(); - return new Vector2D(new double[] { PAD + (arr[0] + 1) / 2.0 * (width - 2 * PAD), - height - PAD - (arr[1] + 1) / 2.0 * (height - 2 * PAD) }); - } - } - - public static void main(String[] args) { - ExampleUtils.showExampleFrame(new Display()); - } -} diff --git a/src/userguide/java/org/apache/commons/math3/userguide/geometry/EnclosingBallExample.java b/src/userguide/java/org/apache/commons/math3/userguide/geometry/EnclosingBallExample.java deleted file mode 100644 index 4293da80c..000000000 --- a/src/userguide/java/org/apache/commons/math3/userguide/geometry/EnclosingBallExample.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.commons.math3.userguide.geometry; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.FlowLayout; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.RenderingHints; -import java.awt.geom.Ellipse2D; -import java.awt.geom.Rectangle2D; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import javax.swing.JComponent; - -import org.apache.commons.math3.geometry.enclosing.Encloser; -import org.apache.commons.math3.geometry.enclosing.EnclosingBall; -import org.apache.commons.math3.geometry.enclosing.WelzlEncloser; -import org.apache.commons.math3.geometry.euclidean.twod.DiskGenerator; -import org.apache.commons.math3.geometry.euclidean.twod.Euclidean2D; -import org.apache.commons.math3.geometry.euclidean.twod.Vector2D; -import org.apache.commons.math3.random.MersenneTwister; -import org.apache.commons.math3.random.RandomGenerator; -import org.apache.commons.math3.userguide.ExampleUtils; -import org.apache.commons.math3.userguide.ExampleUtils.ExampleFrame; - -/** - * Shows how to generate the convex hull of a point cloud in 2D. - */ -public class EnclosingBallExample { - - public static List createRandomPoints(int size) { - RandomGenerator random = new MersenneTwister(); - - // create the cloud container - List points = new ArrayList(size); - // fill the cloud with a random distribution of points - for (int i = 0; i < size; i++) { - points.add(new Vector2D(random.nextDouble() - 0.5, random.nextDouble() - 0.5)); - } - return points; - } - - @SuppressWarnings("serial") - public static class Display extends ExampleFrame { - - public Display() { - setTitle("Commons-Math: Enclosing Ball example"); - setSize(400, 400); - - setLayout(new FlowLayout()); - - Collection cloud = createRandomPoints(150); - Encloser encloser = new WelzlEncloser(1e-10, new DiskGenerator()); - EnclosingBall ball = encloser.enclose(cloud); - - add(new Plot(cloud, ball)); - } - } - - @SuppressWarnings("serial") - public static class Plot extends JComponent { - - private static double PAD = 10; - - private Iterable cloud; - private EnclosingBall ball; - - public Plot(Iterable cloud, EnclosingBall ball) { - this.cloud = cloud; - this.ball = ball; - } - - @Override - protected void paintComponent(Graphics g) { - super.paintComponent(g); - Graphics2D g2 = (Graphics2D)g; - g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, - RenderingHints.VALUE_ANTIALIAS_ON); - - int w = getWidth(); - int h = getHeight(); - - g2.clearRect(0, 0, w, h); - - g2.setPaint(Color.black); - g2.drawRect(0, 0, w - 1, h - 1); - - for (Vector2D point : cloud) { - drawPoint(g2, point, w, h); - } - - g.setColor(Color.RED); - drawCircle(g2, ball.getCenter(), ball.getRadius(), w, h); - } - - private void drawPoint(Graphics2D g2, Vector2D point, int width, int height) { - Vector2D p = transform(point, width, height); - double[] arr = p.toArray(); - g2.draw(new Rectangle2D.Double(arr[0] - 1, arr[1] - 1, 2, 2)); - } - - public void drawCircle(Graphics2D g2, Vector2D center, double radius, int width, int height) { - Vector2D c = transform(center, width, height); - double[] arr = c.toArray(); - double rx = (radius) / 2 * (width - 2 * PAD); - double ry = (radius) / 2 * (height - 2 * PAD); - g2.draw(new Ellipse2D.Double(arr[0] - rx, arr[1] - ry, rx * 2, ry * 2)); - } - - @Override - public Dimension getPreferredSize() { - return new Dimension(300, 300); - } - - private Vector2D transform(Vector2D point, int width, int height) { - double[] arr = point.toArray(); - return new Vector2D(new double[] { PAD + (arr[0] + 0.5) / 2 * (width - 2 * PAD) + width / 4, - height - PAD - (arr[1] + 0.5) / 2 * (height - 2 * PAD) - height / 4 }); - } - } - - public static void main(String[] args) { - ExampleUtils.showExampleFrame(new Display()); - } -} diff --git a/src/userguide/java/org/apache/commons/math3/userguide/geometry/GeometryExample.java b/src/userguide/java/org/apache/commons/math3/userguide/geometry/GeometryExample.java new file mode 100644 index 000000000..b7108f8f8 --- /dev/null +++ b/src/userguide/java/org/apache/commons/math3/userguide/geometry/GeometryExample.java @@ -0,0 +1,162 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.math3.userguide.geometry; + +import java.awt.Color; +import java.awt.geom.Point2D; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.math3.geometry.enclosing.Encloser; +import org.apache.commons.math3.geometry.enclosing.EnclosingBall; +import org.apache.commons.math3.geometry.enclosing.WelzlEncloser; +import org.apache.commons.math3.geometry.euclidean.twod.DiskGenerator; +import org.apache.commons.math3.geometry.euclidean.twod.Euclidean2D; +import org.apache.commons.math3.geometry.euclidean.twod.Segment; +import org.apache.commons.math3.geometry.euclidean.twod.Vector2D; +import org.apache.commons.math3.geometry.euclidean.twod.hull.ConvexHull2D; +import org.apache.commons.math3.geometry.euclidean.twod.hull.ConvexHullGenerator2D; +import org.apache.commons.math3.geometry.euclidean.twod.hull.MonotoneChain; +import org.apache.commons.math3.random.MersenneTwister; +import org.apache.commons.math3.random.RandomGenerator; +import org.apache.commons.math3.util.FastMath; +import org.piccolo2d.PCamera; +import org.piccolo2d.PCanvas; +import org.piccolo2d.PNode; +import org.piccolo2d.event.PBasicInputEventHandler; +import org.piccolo2d.event.PInputEvent; +import org.piccolo2d.extras.PFrame; +import org.piccolo2d.nodes.PPath; +import org.piccolo2d.nodes.PText; + +/** + * Simple example illustrating some parts of the geometry package. + * + * TODO: + * - add user interface to re-generate points + * - select convex hull algorithm + * - select tolerance level + * - allow editing of the point set + * - pre-defined shapes, e.g. circle, cross, ... + */ +public class GeometryExample extends PFrame { + + private static final long serialVersionUID = 1L; + + public GeometryExample() { + this(null); + } + + public GeometryExample(final PCanvas aCanvas) { + super("Geometry example", false, aCanvas); + setSize(600, 600); + } + + public static List createRandomPoints(int size) { + RandomGenerator random = new MersenneTwister(); + + // create the cloud container + List points = new ArrayList(size); + // fill the cloud with a random distribution of points + for (int i = 0; i < size; i++) { + points.add(new Vector2D(FastMath.round(random.nextDouble() * 400 + 100), + FastMath.round(random.nextDouble() * 400 + 100))); + } + return points; + } + + public void initialize() { + List points = createRandomPoints(100); + PNode pointSet = new PNode(); + for (Vector2D point : points) { + final PNode n1 = PPath.createEllipse(point.getX() - 1, point.getY() - 1, 2, 2); + n1.addAttribute("tooltip", point); + n1.setPaint(Color.gray); + pointSet.addChild(n1); + } + + getCanvas().getLayer().addChild(pointSet); + + ConvexHullGenerator2D generator = new MonotoneChain(true, 1e-6); + ConvexHull2D hull = generator.generate(points); + + PNode hullNode = new PNode(); + for (Vector2D vertex : hull.getVertices()) { + final PPath node = PPath.createEllipse(vertex.getX() - 1, vertex.getY() - 1, 2, 2); + node.addAttribute("tooltip", vertex); + node.setPaint(Color.red); + node.setStrokePaint(Color.red); + hullNode.addChild(node); + } + + for (Segment line : hull.getLineSegments()) { + final PPath node = PPath.createLine(line.getStart().getX(), line.getStart().getY(), + line.getEnd().getX(), line.getEnd().getY()); + node.setPaint(Color.red); + node.setStrokePaint(Color.red); + hullNode.addChild(node); + } + + getCanvas().getLayer().addChild(hullNode); + + Encloser encloser = new WelzlEncloser(1e-10, new DiskGenerator()); + EnclosingBall ball = encloser.enclose(points); + + final double radius = ball.getRadius(); + PPath ballNode = PPath.createEllipse(ball.getCenter().getX() - radius, ball.getCenter().getY() - radius, radius * 2, radius * 2); + ballNode.setTransparency(1.0f); + ballNode.setStrokePaint(Color.blue); + getCanvas().getLayer().addChild(0, ballNode); + + final PCamera camera = getCanvas().getCamera(); + + final PText tooltipNode = new PText(); + + tooltipNode.setPickable(false); + camera.addChild(tooltipNode); + + camera.addInputEventListener(new PBasicInputEventHandler() { + public void mouseMoved(final PInputEvent event) { + updateToolTip(event); + } + + public void mouseDragged(final PInputEvent event) { + updateToolTip(event); + } + + public void updateToolTip(final PInputEvent event) { + final PNode n = event.getPickedNode(); + final Object object = (Object) n.getAttribute("tooltip"); + if (object != null) { + final String tooltipString = object.toString(); + final Point2D p = event.getCanvasPosition(); + + event.getPath().canvasToLocal(p, camera); + + tooltipNode.setText(tooltipString); + tooltipNode.setOffset(p.getX() + 8, p.getY() - 8); + } else { + tooltipNode.setText(null); + } + } + }); + } + + public static void main(final String[] argv) { + new GeometryExample(); + } +} \ No newline at end of file diff --git a/src/userguide/pom.xml b/src/userguide/pom.xml index 77f6c5a39..19aa2cf9d 100644 --- a/src/userguide/pom.xml +++ b/src/userguide/pom.xml @@ -56,8 +56,18 @@ com.xeiam.xchart xchart - 2.2.1 + 2.3.0 + + org.piccolo2d + piccolo2d-core + 3.0 + + + org.piccolo2d + piccolo2d-extras + 3.0 + org.apache.commons commons-lang3