首页 > 解决方案 > 双不等式怎么可能在两个相等的双打上成功?

问题描述

我有一段我无法理解的代码片段。

给出一些上下文:我有一条线(由它的 angular coefficient 定义m),我搜索一组线段以找到相交的线段。一个段和一个段向量定义为:

typedef std::pair<Eigen::Vector2d, Eigen::Vector2d> Vector2dPair;
typedef std::vector<Vector2dPair> Vector2dPairVector;

提到的代码是(提供一个最小的工作示例):

#include <iostream>
#include <Eigen/Dense>

typedef std::vector<Eigen::Vector2d> Vector2dVector;
typedef std::pair<Eigen::Vector2d, Eigen::Vector2d> Vector2dPair;
typedef std::vector<Vector2dPair> Vector2dPairVector;

int main()
{
  Vector2dPair segment;
  segment.first = Eigen::Vector2d(2, -2);
  segment.second = Eigen::Vector2d(2, 2);

  Vector2dPairVector segments;
  segments.push_back(segment);

  double angle_min = 0;
  double angle_max = M_PI_4;
  double angle_increment = M_PI / 16.0;
  double range_min = 0.0;
  double range_max = 10.0;

  Vector2dVector points;

  double field_of_view = angle_max - angle_min;
  int num_ranges = static_cast<int>(std::nearbyint(std::abs(field_of_view) / angle_increment));

  std::cerr << "fov: " << field_of_view << std::endl;
  std::cerr << "num ranges: " << num_ranges << std::endl;

  points.resize(num_ranges);

  for (int i = 0; i < num_ranges; ++i)
  {
    const double angle = angle_min + i * angle_increment;

    std::cerr << "angle: " << angle << std::endl;

    const double m = std::tan(angle);

    Eigen::Vector2d point = Eigen::Vector2d::Zero();
    bool found = false;

    for (const auto& segment : segments)
    {
      // compute segment coefficients (a*x + b*y = c)
      double a = segment.second.y() - segment.first.y();
      double b = segment.first.x() - segment.second.x();
      double c = a * segment.first.x() + b * segment.first.y();

      // build A matrix and w vector to setup linear system of equation
      Eigen::Matrix2d A;
      A << -m, 1, a, b;

      Eigen::Vector2d w;
      w << 0, c;

      // solve linear system to find point of intersection
      Eigen::Vector2d p = A.colPivHouseholderQr().solve(w);

      // check that the point lies inside the segment
      double x_min = std::min(segment.first.x(), segment.second.x());
      double x_max = std::max(segment.first.x(), segment.second.x());

      double y_min = std::min(segment.first.y(), segment.second.y());
      double y_max = std::max(segment.first.y(), segment.second.y());

      // point is outside the segment
      if (p.x() < x_min || p.x() > x_max || p.y() < y_min || p.y() > y_max)
      {
        std::cerr << "p: " << p.transpose() << std::endl;

        std::cerr << "min: " << x_min << ", " << y_min << std::endl;
        std::cerr << "max: " << x_max << ", " << y_max << std::endl;

        std::cerr << (p.x() < x_min ? "true" : "false") << std::endl;
        std::cerr << (p.x() > x_max ? "true" : "false") << std::endl;
        std::cerr << (p.y() < y_min ? "true" : "false") << std::endl;
        std::cerr << (p.y() > y_max ? "true" : "false") << std::endl;

        continue;
      }

      std::cerr << "found" << std::endl;
      found = true;
      point = p;
      break;
    }

    if (!found)
    {
      throw std::runtime_error("wtf!!");
    }
    std::cerr << std::endl;
  }

  return 0;
}

奇怪的是,在某些时候,最终检查的行为并不像预期的那样。特别是,我得到:

p:        2 0.828427
min: 2, -2
max: 2, 2
true
false
false
false

那就是检查p.x() < x_mintrue什么时候p.x() = 2x_min = 2

有人可以告诉我有什么问题吗?

谢谢。

标签: c++doubleeigeninequality

解决方案


我发现了问题。像往常一样,电脑是对的!!!

通过做:

std::cerr.precision(60);

我发现:

p: 1.999999999999999555910790149937383830547332763671875000000000 0.828427124746190735038453567540273070335388183593750000000000
min: 2.000000000000000000000000000000000000000000000000000000000000, -2.000000000000000000000000000000000000000000000000000000000000
max: 2.000000000000000000000000000000000000000000000000000000000000, 2.000000000000000000000000000000000000000000000000000000000000
true
false
false
false
terminate called after throwing an instance of 'std::runtime_error'
  what():  wtf!!

推荐阅读