【问题标题】:Find the arc of the intersection between circle and rectangle求圆与长方形相交的圆弧
【发布时间】:2014-05-01 13:23:11
【问题描述】:

我需要找到从圆和矩形的交点创建的最大弧。我有圆心,矩形的半径和坐标,我需要找到交点与圆心的角度。

我有一个有效的代码,但它计算迭代圆周点的解决方案,我想知道是否有更优雅的方法来使用三角函数而不是“蛮力”来计算解决方案。

这是我的代码:

import 'dart:math';

class CircleTheSquare {
  final Point     _circleCenter;
  final int       _circleRadius;
  final Rectangle _box;


  CircleTheSquare(this._circleCenter, this._circleRadius, this._box);


  Map<String, double> get arc {
    Map res = new Map();

    double angle = .0;
    double angleIn;
    double angleOut;
    double increment = 1.0;

    while (true) {
      if (angle > 360.0 && angleIn == null) {
        break;
      }

      // Finds a point of intersection (next points will be inside 
      // of the rectangle).
      if (!_isOutside(angle) && _isOutside(angle - increment)) {
        angleIn = angle;
      }

      // Finds next intersection (next points will be outside 
      // of the rectangle).
      if (angleIn != null &&
          _isOutside(angle + increment) && !_isOutside(angle)) {

        angleOut = angle;

        // Adds the arc to result only there's not a previous largest arc.
        if (res["in"] == null ||
            angleOut - angleIn > res["arc"]) {

          res["in"]  = angleIn;
          res["arc"] = angleOut - angleIn;
        }
        angleIn = null;
        angleOut = null;
      }
      angle += increment;
    }

    // If there's no intersections. 
    // -- For simplicity, we will assume that the
    //    rectangle and the circle intersect or that the circle is 
    //    inside of the rectangle).
    if (res["in"] == null) {
      res = {"in" : 0.0, "arc" : 360.0};
    }

    return res;
  }


  bool _isOutside(double a) {
    var res;

    double cx = _circleCenter.x + (_circleRadius * cos(a * (PI / 180)));
    double cy = _circleCenter.y + (_circleRadius * sin(a * (PI / 180)));

    bool hOut = cx < _box.left || cx > _box.left + _box.width;
    bool vOut = cy < _box.top || cy > _box.top + _box.height;

    if (hOut || vOut) {
      res = true;
    } else {
      res = false;
    }

    return res;
  }
}


main() {
  CircleTheSquare a = new CircleTheSquare(new Point(250, 250), 100,
                                          new Rectangle(0,0,500,500));

  print(a.arc); // {in: 0.0, arc: 360.0}

  CircleTheSquare b = new CircleTheSquare(new Point(450, 250), 100,
                                          new Rectangle(0,0,500,500));

  print(b.arc); // {in: 60.0, arc: 240.0}

  CircleTheSquare c = new CircleTheSquare(new Point(420, 420), 100,
                                          new Rectangle(0,0,500,500));

  print(c.arc); // 4 intersections, returns the largest arc:
                          // {in: 127.0, arc: 196.0}
}

【问题讨论】:

  • 这更像是数学问题而不是编程问题。
  • 想象一个与正方形同心的圆,有 8 个交点。最大的弧在哪里?
  • 对于我试图解决的问题,这并不意味着发生。圆的直径总是小于矩形的短边。

标签: algorithm math dart trigonometry intersection


【解决方案1】:

如您所料,有更好更直接的方法来解决这个问题。你可能想看看例如http://mathworld.wolfram.com/Circle-LineIntersection.html。将矩形分割成线,获取每条线的交点,确定它们是否在实际线段内,然后找到给出最大弧的点。

【讨论】:

    【解决方案2】:
    1. 为了简单起见,移动所有坐标以使圆以零为中心(box.left = box.left - circlecenter.x 等)
    2. 查找圆与矩形边的交点。例如,对于左侧求解 (box.left)^2 + y^2 = radius^2,检查点是否在一边,将交点添加到列表中
    3. 对交点按角度排序(可能是边检顺序自动提供的),求矩形内圆弧的最大角度区间

    【讨论】:

      猜你喜欢
      • 2017-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-12
      相关资源
      最近更新 更多