仅使用余弦来检查Delaunay的“翻转条件”

如何解决仅使用余弦来检查Delaunay的“翻转条件”

在寻找确定点是否在外接圆内的方法时,我遇到了this答案,该答案使用了一种有趣的方法在点和三角形之间构造四边形并测试flip condition看看新点是否构成更好的delaunay三角形,并因此在原始三角形的外接圆之内。

delaunay翻转条件处理角度,但是,我发现的answer只是计算角度的余弦值。而不是检查角度的总和是否小于或等于180°,它采用所有(负)余弦中的最小值,比较这两个结果以确定点是否在圆中。

以下是该答案的代码(为方便起见,在此处复制):

#include <array>
#include <algorithm>

struct pnt_t
{
  int x,y;

  pnt_t ccw90() const
    { return { -y,x }; }

  double length() const
    { return std::hypot(x,y); }

  pnt_t &operator -=(const pnt_t &rhs)
  {
    x -= rhs.x;
    y -= rhs.y;
    return *this;
  }

  friend pnt_t operator -(const pnt_t &lhs,const pnt_t &rhs)
    { return pnt_t(lhs) -= rhs; }

  friend int operator *(const pnt_t &lhs,const pnt_t &rhs)
    { return lhs.x * rhs.x + lhs.y * rhs.y; }
};

int side(const pnt_t &a,const pnt_t &b,const pnt_t &p)
{
  int cp = (b - a).ccw90() * (p - a);
  return (cp > 0) - (cp < 0);
}

void make_ccw(std::array<pnt_t,3> &t)
{
  if (side(t[0],t[1],t[2]) < 0)
    std::swap(t[0],t[1]);
}

double ncos(pnt_t a,const pnt_t &o,pnt_t b)
{
  a -= o;
  b -= o;
  return -(a * b) / (a.length() * b.length());
}

bool inside_circle(std::array<pnt_t,3> t,const pnt_t &p)
{
  make_ccw(t);

  std::array<int,3> s = 
    { side(t[0],p),side(t[1],t[2],side(t[2],t[0],p) };

  unsigned outside = std::count(std::begin(s),std::end(s),-1);
  if (outside != 1)
    return outside == 0;

  while (s[0] >= 0)
  {
    std::rotate(std::begin(t),std::begin(t) + 1,std::end(t));
    std::rotate(std::begin(s),std::begin(s) + 1,std::end(s));
  }

  double 
    min_org = std::min({
      ncos(t[0],t[2]),ncos(t[2],t[1]),ncos(t[1],ncos(p,t[0]) }),min_alt = std::min({
      ncos(t[1],t[0]),ncos(t[0],p,t[1]) });

  return min_org <= min_alt;
}

我无法理解其工作原理。

“角度之和”与“所有余弦的最小值”如何关联?某些角度的余弦值始终为负,我认为您可以将三角形的位置任意地落在该负范围内。那么该测试如何有效?

另外,在收集了两组“最小余弦”(而不是两组角度和)之后,最终测试是查看哪个最小值最小。同样,我看不到这与通过使用翻转条件确定三角形是否有效的原始测试有什么关系。

我想念什么?

解决方法

好消息是,有一个众所周知的函数,可以通过计算以下所示的行列式来确定点D是否位于三角形ABC的外接圆内。如果InCircle返回大于零,则D位于外接圆内,需要翻转。该公式确实假定三角形ABC是按逆时针顺序给出的(因此具有正面积)。

enter image description here

我从成等人的书中得到了这个方程。 “ Delaunay Mesh Generation”(2013年),但您应该可以在其他地方找到它。 https://github.com/gwlucastrig/Tinfour提供了开放源Java实现,但是我敢肯定,您可以在其他地方找到示例,其中一些示例可能更适合您的需求。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?