【问题标题】:Wraping of two dimensional point set二维点集的包装
【发布时间】:2015-03-09 23:29:50
【问题描述】:

我有一个二维点列表。

例如:

x=c(4,3,3,5,6,6,4)

y=c(5,3,1,0,1,3,5)

这些二维点的图是

我想画一个这样的点集的包装:

请注意,边界(包装)与最近点之间的垂直距离为 2 个单位。

请注意:我有许多点集,如上述点集。我想对所有的集合做同样的事情。

我想要这个边界多边形。谁能建议我如何做到这一点。

任何想法都非常感谢,Janak。

【问题讨论】:

  • 点坐标可以是任意浮点值吗?是否保证结果将是一个连贯的多边形,没有“洞”?
  • @laune..抱歉回复晚了。对于您提出的两个问题,答案都是肯定的(点坐标是任意浮点和没有孔的单个连贯多边形)。感谢您的关注。
  • 我还是不太明白你在问什么。您是否要求一种算法从点集生成边界或将点从给定边界移开?
  • 我正在尝试 - 这可能有漏洞。计算正方形集,它们的角点集是 C。计算所有相交矩形,它们的角点集是 R。显然,多边形的点必须是 U(C, R) 的子集。 - 要构建路径,请从一个最大的正方形开始。 y 坐标。垂直边可能相交也可能不相交:如果相交,则找到最近的交点和导致它的正方形;如果没有,请在拐角处转弯并沿着那一侧前进。继续前行,直到到达第一个方格。
  • 浮点坐标可能需要注意。通过缩放 (*1000000) 转换为 long 并返回可能是一种选择。

标签: java r algorithm


【解决方案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 );
}
}

【讨论】:

  • 谢谢劳恩。我非常感谢你的努力。我很快就会告诉你结果。
  • 嗨 laune 我试图运行你的代码,但它给出了错误,我无法解决它。请检查一下。
  • 你遇到了什么错误?你有什么改变吗? - 它可以在我的系统 JDK 1.8 上干净地运行,但也应该在 1.7 或 1.6 上运行。
  • 我在 ubunto 14.10 中使用 JDK 1.6、Eclipse。程序第一部分显示的错误是:线程“main”java.lang.Error中的异常:未解决的编译问题:在day1.PointSet.main(PointSet.java:14)
  • 您已插入导入 - 那么这是哪一行以及它的外观。这是一个编译问题——你可能打错了。
【解决方案2】:

要实现这一点,您可以使用这个简单的算法。
首先,我们需要您的坐标中心(红点)
这可以通过添加所有 x 值并将结果除以它们的数量来完成,与 y 值相同。

下一步将计算一个矩形,它包含当前坐标和中心点。 (不要忘记在此处添加 2 个单位的偏移量)

我们将对所有坐标执行此操作

此时我们已经可以停下来了。只需渲染所有这些矩形,然后在图片顶部渲染您的坐标,但让我们再改进一点。
我们实际上并不需要所有这些矩形,我们想要的是一个多边形来包裹这些点。 这个多边形是由我们的 retangles 和它们的边缘(蓝点)的交点定义的。

请注意,我们只需要距离中心最远的边缘和交叉点。
我们现在可以通过连接共享一个公共坐标并且是“邻居”的点来连接这些蓝点。


更新:

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]


附注: 我试图从这一点改进算法,但遇到了一个似乎很难解决的问题——也许我会就这个问题提出一个新问题。
(它是关于带有蓝点的图片。一旦你从矩形及其交点中获得所有点,就很难找出我们的多边形实际上需要哪些结果点)。我想我已经接近解决方案了,所以请注意我的下一次编辑。

【讨论】:

  • 感谢蒂姆为解决我的问题所做的巨大努力。很期待JAVA代码的解决方法,不过不急,有时间可以做。祝您考试顺利。
  • 您能否检查一下我是否正确使用您的 JAVA 代码。假设我们取点为(1,2); (2,5) 和 (3,2),然后中心是 (3,3)。但是在这里使用您的参数可能无法找到上述类型的边界。
  • 嘿 janak,我很抱歉,但我的代码还没有完成,我得到了所有的矩形,并将尽快摆脱这些额外的点。我希望在今晚之前完成它。这些点的中心将是 (2,3),而上述点 (2,5) 的边界将是我偶然编写此算法的一个特例。解决方案是添加您描述的 2 个单位的边距,以便找到一个环绕矩形。这个矩形的宽度为 2*margin(我真的希望我的问题是正确的,但我现在有点着急)。
  • 嗨蒂姆我运行你的代码。它运行良好,我理解你提到的问题。期待您对解决此问题的代码进行下一次编辑。
  • @TimHallyburton 您的方法存在重大缺陷。可以有一组点来创建重叠的正方形集,从而形成一个形状,该形状将通过构建包含正方形和“红色中心”的矩形来扩大。即使是简单的集合 (0,0);(2,2);(4,4);(6,6);就足够了,因为两端的两个正方形都被放大到包括 (3,3),即“红色中心”。
猜你喜欢
  • 2014-05-27
  • 1970-01-01
  • 2018-05-07
  • 1970-01-01
  • 2018-01-31
  • 2014-01-05
  • 2013-02-09
  • 2022-11-05
  • 1970-01-01
相关资源
最近更新 更多