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
This commit is contained in:
parent
06e1ff5008
commit
12ddf37f23
|
@ -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<Vector2D> createRandomPoints(int size) {
|
||||
RandomGenerator random = new MersenneTwister();
|
||||
|
||||
// create the cloud container
|
||||
List<Vector2D> points = new ArrayList<Vector2D>(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<Vector2D> 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<Vector2D> cloud;
|
||||
private ConvexHull2D hull;
|
||||
|
||||
public Plot(Iterable<Vector2D> 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());
|
||||
}
|
||||
}
|
|
@ -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<Vector2D> createRandomPoints(int size) {
|
||||
RandomGenerator random = new MersenneTwister();
|
||||
|
||||
// create the cloud container
|
||||
List<Vector2D> points = new ArrayList<Vector2D>(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<Vector2D> cloud = createRandomPoints(150);
|
||||
Encloser<Euclidean2D, Vector2D> encloser = new WelzlEncloser<Euclidean2D, Vector2D>(1e-10, new DiskGenerator());
|
||||
EnclosingBall<Euclidean2D, Vector2D> ball = encloser.enclose(cloud);
|
||||
|
||||
add(new Plot(cloud, ball));
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public static class Plot extends JComponent {
|
||||
|
||||
private static double PAD = 10;
|
||||
|
||||
private Iterable<Vector2D> cloud;
|
||||
private EnclosingBall<Euclidean2D, Vector2D> ball;
|
||||
|
||||
public Plot(Iterable<Vector2D> cloud, EnclosingBall<Euclidean2D, Vector2D> 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());
|
||||
}
|
||||
}
|
|
@ -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<Vector2D> createRandomPoints(int size) {
|
||||
RandomGenerator random = new MersenneTwister();
|
||||
|
||||
// create the cloud container
|
||||
List<Vector2D> points = new ArrayList<Vector2D>(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<Vector2D> 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<Euclidean2D, Vector2D> encloser = new WelzlEncloser<Euclidean2D, Vector2D>(1e-10, new DiskGenerator());
|
||||
EnclosingBall<Euclidean2D, Vector2D> 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();
|
||||
}
|
||||
}
|
|
@ -56,8 +56,18 @@
|
|||
<dependency>
|
||||
<groupId>com.xeiam.xchart</groupId>
|
||||
<artifactId>xchart</artifactId>
|
||||
<version>2.2.1</version>
|
||||
<version>2.3.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.piccolo2d</groupId>
|
||||
<artifactId>piccolo2d-core</artifactId>
|
||||
<version>3.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.piccolo2d</groupId>
|
||||
<artifactId>piccolo2d-extras</artifactId>
|
||||
<version>3.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
|
|
Loading…
Reference in New Issue