【问题标题】:iterate through each point on a line/path in java遍历java中行/路径上的每个点
【发布时间】:2015-07-11 03:06:16
【问题描述】:

我是使用迭代器的新手,想知道如何遍历线段上的每个点(准确地说是 Line2D.Double)——我需要检查线上的每个点是否满足某些要求.

另外,给定一个路径对象(如 GeneralPath),你会如何做同样的事情(遍历形状轮廓上的每个点)?

理想情况下,我想要这样的东西(有一条线或一条路径):

Line2D line = new Line2D.Double(p1,p2);
for (Point2D point : line)
{
   point.callSomeMethod();
}

【问题讨论】:

    标签: java path iterator line point


    【解决方案1】:

    Java API 中似乎没有任何东西使 Bresenham 的算法对用户可见。 So I wrote a class that iterates over a line.

    你可以这样使用它:

    List<Point2D> points = new ArrayList<Point2D>();
    Line2D line = new Line2D.Double(0, 0, 8, 4);
    Point2D current;
    
    for (Iterator<Point2D> it = new LineIterator(line); it.hasNext();) {
        current = it.next();
        points.add(current);
    }
    
    assertThat(points.toString(), 
        is("[Point2D.Double[0.0, 0.0], Point2D.Double[1.0, 0.0], " +
            "Point2D.Double[2.0, 1.0], Point2D.Double[3.0, 1.0], " +
            "Point2D.Double[4.0, 2.0], Point2D.Double[5.0, 2.0], " +
            "Point2D.Double[6.0, 3.0], Point2D.Double[7.0, 3.0], " +
            "Point2D.Double[8.0, 4.0]]"));
    

    【讨论】:

    • 非常感谢,您将所有点都放在网上的逻辑很棒。这对我来说效果很好。
    • 谢谢!你为我节省了几个小时!
    • 链接似乎已过时。您可以更新它或提供代码作为答案的一部分吗?
    【解决方案2】:

    这会很慢,因为它会为每个点生成一个新对象。如果您需要更快的解决方案,您可能需要考虑使用Bresenham algorithm 自己实现循环。

    【讨论】:

    • 这可能是真的,也可能不是。 Ecapa 分析风格优化使得每次都不需要创建新对象。仍然投票,因为这是唯一至少有一点意义的答案。
    • 没错,JVM 可以“优化掉”对象。
    【解决方案3】:

    虽然您的问题缺少很多相关信息(即我猜测您的课程很多),但最简洁的循环代码是 foreach 语法:

    GeneralPath path = ...;
    for (Line2D.Double point : path.getPoints()) {
        // do something
    }
    

    但是请注意,您不能使用这种循环修改被迭代的对象。

    【讨论】:

    • 我正在寻找与 foreach 循环几乎完全一样的东西,但我只是尝试过,GeneralPath 没有名为 getPoints() 的方法(Line2D 也没有)......另外,我不会想要在参数中为 (Point2D...) 而不是 Line2D 做?
    【解决方案4】:

    使用 FlatteningPathIterator 传递 Shape 的路径迭代器。

    【讨论】:

      【解决方案5】:

      检查返回的类型:

      • PathIterator.SEG_MOVETO
      • PathIterator.SEG_LINETO
      • PathIterator.SEG_QUADTO
      • PathIterator.SEG_CUBICTO
      • PathIterator.SEG_CLOSE

      代码:

      PathIterator pi = path.getPathIterator(null);
      
      while (pi.isDone() == false) {
          double[] coordinates = new double[6];
          int type = pi.currentSegment(coordinates);
          pi.next();
      }
      

      【讨论】:

      • 但是,(根据我对迭代器的有限理解)这不会只给我路径的每一段的起点/终点,而不是路径上的每一个点吗?
      • 你是对的,但是在一条线上,你可以获得无限数量的点。所以如果你得到了一条线段的起点和终点,为什么不根据你想要的精度来计算自己呢?
      • 已编辑:我误解了你的问题,看前面的评论就够了,记住两点形式,你可以自己获取坐标。 //我觉得可以先用 Line2D.Double(double X1, double Y1, double X2, double Y2) 创建 Line2D,然后用 Line2D 方法 contains(double x, double y) 检查点是否在行
      猜你喜欢
      • 1970-01-01
      • 2014-02-04
      • 1970-01-01
      • 2019-04-25
      • 2016-01-10
      • 2020-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多