我有一个二维点的列表。
例如:
X = C(4,3,3,5,6,6,4)
和
Y = C(5,3,1,0,1,3,5)
这些二维点的图是
我想画一个像这样的点集的包装:
请注意,边界(包装)与最近点之间的垂直距离为2个单位。
注意:我有很多像上面的点集一样的点集。我想为所有的集合做同样的事情。
我想要这个边界多边形。任何人都可以建议我如何做到这一点。
任何想法都非常感谢,Janak。
答案 0 :(得分:3)
要实现这一目标,您可以使用这种简单的算法
首先,我们需要坐标中心(红点)
这可以通过添加所有x值并将结果除以其数量来完成,与y值相同
下一步是计算包含当前坐标和中心点的矩形。 (别忘了在这里添加2个单位的偏移量)
我们将为所有坐标执行此操作
此时我们已经停止了。只需渲染所有这些矩形,然后渲染图片上方的坐标,但让我们稍微改进一下。
我们实际上并不需要所有这些矩形,我们想要的是包裹这些点的多边形。
此多边形由我们的重新校正及其边缘(蓝点)的交点定义。
请注意,我们只需要距离我们中心最远的边缘和交叉点。
我们现在可以通过连接共享一个公共坐标并且是“邻居”的点来连接这些蓝点。
的更新强>
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
public class PolyWrapper {
public static void main(String[] args){
//your example coords:
int[] x_coords = {4,3,3,5,6,6,4};
int[] y_coords = {5,3,1,0,1,3,5};
//make sure the coordinates have the same length, else they won't match
if(x_coords.length != y_coords.length){
System.err.println("Bad parameters given. X and Y don't match!");
System.exit(1);
}
//this will hold our points:
ArrayList<Point2D> points = new ArrayList<>();
for(int i = 0; i < x_coords.length; i++){
Point2D p = new Point2D.Double(x_coords[i], y_coords[i]);
points.add(p);
}
//lets get the center of all those points:
final Point2D center = get_center(points);
ArrayList<Rectangle2D> rectangles = new ArrayList<>();
//now lets create those wrapping rectangles:
for(Point2D p : points){
Rectangle2D r = new Rectangle2D.Double();
r.setFrameFromDiagonal(center, p);
rectangles.add(r);
}
//now show the wrapping rectangles:
for(Rectangle2D r : rectangles){
System.out.println(r.toString());
}
}
//this method returns the center of a list of points
public static Point2D get_center(ArrayList<Point2D> points){
double x = 0,y =0;
for(Point2D p : points){
x += p.getX();
y += p.getY();
}
x = x / points.size();
y = y / points.size();
Point2D c = new Point2D.Double();
c.setLocation(x, y);
return c;
}
}
所以这是一些示例代码。我还没有时间完成它,但由于你的问题非常有趣,我会继续努力。
到目前为止,此代码计算中心点并围绕中心和给定坐标创建矩形。
此输出提供每个矩形的左上角,它的宽度和高度。
样本输出:
java.awt.geom.Rectangle2D$Double[x=4.0,y=2.5714285714285716,w=0.4285714285714288,h=2.4285714285714284]
java.awt.geom.Rectangle2D$Double[x=3.0,y=2.5714285714285716,w=1.4285714285714288,h=0.4285714285714284]
java.awt.geom.Rectangle2D$Double[x=3.0,y=1.0,w=1.4285714285714288,h=1.5714285714285716]
java.awt.geom.Rectangle2D$Double[x=4.428571428571429,y=0.0,w=0.5714285714285712,h=2.5714285714285716]
java.awt.geom.Rectangle2D$Double[x=4.428571428571429,y=1.0,w=1.5714285714285712,h=1.5714285714285716]
java.awt.geom.Rectangle2D$Double[x=4.428571428571429,y=2.5714285714285716,w=1.5714285714285712,h=0.4285714285714284]
java.awt.geom.Rectangle2D$Double[x=4.0,y=2.5714285714285716,w=0.4285714285714288,h=2.4285714285714284]
P.S .:
我试图从这一点改进算法,但遇到了一个似乎很难解决的问题 - 也许我会开始一个关于这个问题的新问题。
(它是关于带有蓝点的图片。一旦你从矩形及其交叉点得到所有点,就很难找出我们的多边形实际上需要哪些结果点)。我认为我接近解决方案,所以请留意我的下一次编辑。
答案 1 :(得分:1)
使用Java,这变得非常简单。该程序通过绘制它来演示结果。也可以通过迭代area.getPathIterator(at)
来获得轮廓,import java.awt.*;
import java.awt.geom.*;
import java.util.*;
public class PointSet {
public static final int W = 2;
Area area = new Area();
public void add( double x, double y ){
area.add( new Area( new Rectangle2D.Double( x-W, y-W,2*W, 2*W ) ) );
}
public void plot(){
Board board = new Board();
board.go( area );
}
public static void main( String[] args ){
PointSet ps = new PointSet();
ps.add( 4, 5);
ps.add( 3, 3);
ps.add( 3, 1);
ps.add( 5, 0);
ps.add( 6, 1);
ps.add( 6, 3);
ps.plot();
}
}
将逐一返回所有点。
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
import java.util.*;
public class Board extends JPanel {
Area area;
void go( Area area ) {
this.area = area;
JFrame frame = new JFrame("Circle Test");
frame.getContentPane().add(this);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
repaint();
frame.setPreferredSize(new Dimension(800,800));
frame.pack();
frame.setVisible(true);
}
public void paintComponent(Graphics g) {
AffineTransform at = new AffineTransform();
at.translate( 100, 100 );
at.scale( 50, 50 );
PathIterator pit = area.getPathIterator( at );
Path2D path = new Path2D.Double();
path.append( pit, true );
Graphics2D g2d = (Graphics2D)g;
g2d.draw( path );
}
}
和
{{1}}