在 C++ 中找到一对椭圆的公切线的首选方法[关闭]

2024-01-23

我想用 C++ 来做这个。我有两个想法可以做到这一点:

  1. 将这对椭圆视为两个不同参数的参数方程,我可以根据这两个参数得到两个方程。这对方程是非线性的,都是余切、正弦和余弦的函数。 Geant4,这是我主要使用的,只有多项式
  2. 使用几何库来解决这个问题。我查看了 Boost 几何,但文档不连贯(对我来说)。话虽如此,它似乎更针对计算几何。也许我要求它做 Y,而它本来只想做 X。

人们可以怎样做呢?在Python中这很容易,我可以在睡梦中完成。任何见解将不胜感激。自从我开始使用 C++ 以来,感觉选择要使用的库本身就是一场巨大的战斗。


我有一些建议。您可以尝试 LibreCAD,它有一个求解两个椭圆的公切线的解算器,但我对 API 一无所知。求解器求解四次方程,如果您天真地尝试找到两个椭圆的公切线,就会得到这个结果。

如果您想自己动手:只需一点理论(“二次曲线范围”),您所要求的就可以通过线性代数(即求 3x3 矩阵的逆)加上求解二次方程和一个三次方程来完成。事情是这样的:

您可以用矩阵方程的形式表达任何二次曲线(例如椭圆)

        [m00 m01 m02] [x]
[x,y,z] [m10 m11 m12] [y] = 0
        [m20 m21 m22] [z]

其中矩阵M是对称的并且[x,y,z]是齐次坐标;想一想z=1。我们可以将该方程简写为X M X^T = 0 where X^T是转置X.

平面上的直线可以写成以下形式lx+my+nz=0所以有“线坐标”(l,m,n).

上述二次曲线的切线组可以用这种表示法非常简单地表达。让A是矩阵的逆矩阵M。那么圆锥曲线的切线集是

        [a00 a01 a02] (l)
(l,m,n) [a10 a11 a12] (m) = 0
        [a20 a21 a22] (n)

现在假设我们有第二个带有矩阵的二次曲线N, 然后N有逆的B。公切线将满足上述方程和方程

        [b00 b01 b02] (l)
(l,m,n) [b10 b11 b12] (m) = 0
        [b20 b21 b22] (n)

事实上,我们可以将后一个方程中的矩阵标量乘以t并且它仍然会保持:

          [b00 b01 b02] (l)
(l,m,n) t [b10 b11 b12] (m) = 0
          [b20 b21 b22] (n)

将第一个二次曲线的切线方程添加到上述第二个二次曲线的方程中,我们得到矩阵方程L (A + tB) L^T = 0。因此,两个二次曲线的任何公切线都是“范围”中每个二次曲线的公切线A + tB.

现在,对于大的简化想法:我们可以在该范围内找到一些非常特殊的二次曲线,“退化”二次曲线,它们只是点对。由于公切线必须穿过所有二次曲线,因此它们必须穿过简并二次曲线。但是很容易找到穿过简并二次曲线的线,因为这样的二次曲线只是点对!

通过求解三次方程可以找到简并二次曲线det(A + tB) = 0 where det()是 3x3 矩阵的行列式。三次方程可以通过卡尔达诺公式或变体以封闭形式求解,或者如果您需要的话,也可以通过数值求解。一旦找到以下值t这使得退化二次曲线,你可以分解方程L (A + tB) L^T = 0分解为两个线性因子。每个线性因子xl + ym + zn = 0定义齐次坐标中的点[x,y,z],或在笛卡尔坐标系中(x/z,y/z)。您应该以这种方式获得三个点对(六个点)。通过某些点对绘制直线将为您提供四条(最多)切线。

这是一个简单的例子(其中两个椭圆的中心都在原点):找到公切线x^2+2y^2=3 and x^2+14y^2=7。矩阵形式的二次曲线是

        [1 0  0] [x]               [1  0  0] [x]
[x,y,z] [0 2  0] [y] = 0,  [x,y,z] [0 14  0] [y] = 0
        [0 0 -3] [z]               [0  0 -7] [z]

切线由下式给出

        [6 0  0] (l)               [14 0  0] (l)
(l,m,n) [0 3  0] (m) = 0,  (l,m,n) [ 0 1  0] (m) = 0
        [0 0 -2] (n)               [ 0 0 -2] (n)

请注意,我将逆矩阵乘以标量只是为了使条目成为整数而不是有理数。您不必这样做,但它使手工计算更容易。将第二个矩阵乘以另一个标量t gives

        [6+14t 0    0   ] (l)
(l,m,n) [0     3+t  0   ] (m) = 0
        [0     0   -2-2t] (n)

圆锥曲线是退化的,当(6+14t)(3+t)(-2-2t)=0,即当t=-3/7, -3, -1. When t=-3/7 we get

18/7 m^2 - 8/7 n^2 = 2/7 (9 m^2 - 4 n^2) = 2/7 (3m - 2n)(3m + 2n) = 0

这对应于具有齐次坐标的点[x,y,z] = [0,3,-2] and [0,3,2],换句话说就是具有笛卡尔坐标的点(0,-3/2) and (0,3/2).

When t=-3 we get -36l^2 + 4n^2 = (6l+2n)(-6l+2n) = 0, 点[6,0,2] and [-6,0,2]或在笛卡尔坐标系中(3,0) and (-3,0)。最后,当t=1 we get -8l^2 + 2m^2 = 2(2l+m)(-2l+m) = 0对应点[2,1,0] and [-2,1,0]它们是无穷远点。

现在避免无穷远点,只是因为它们更难处理,我们通过以下两对点得到四条线:

{(0,-3/2),(-3,0)}, {(0,-3/2),(3,0)}, {(0,3/2),(-3,0)}, {(0,3/2),(3,0)}

这给了我们两个椭圆的四个公切线。

从图中可以看出,公切线也经过无穷远点[2,1,0] and [-2,1,0],即平行线对具有斜率1/2 and -1/2.

那不是很漂亮吗?

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 C++ 中找到一对椭圆的公切线的首选方法[关闭] 的相关文章

  • EventHandler 应该始终用于事件吗?

    我一直在愉快地使用自定义委托类型和通用编写事件Action委托类型 没有真正考虑我在做什么 我有一些很好的扩展助手Action and EventHandler这使我倾向于使用那些预定义的委托类型而不是我自己的委托类型 但除此之外 除了惯例
  • OpenGL缓冲区更新[重复]

    这个问题在这里已经有答案了 目前我正在编写一个模拟水的程序 以下是我所做的步骤 创建水面 平面 创建VAO 创建顶点缓冲区对象 在其中存储法线和顶点 将指针绑定到此 VBO 创建索引缓冲区对象 然后我使用 glDrawElements 渲染
  • 在 Mac OS X 上安装 libxml2 时出现问题

    我正在尝试在我的 Mac 操作系统 10 6 4 上安装 libxml2 我实际上正在尝试在 Python 中运行 Scrapy 脚本 这需要我安装 Twisted Zope 现在还需要安装 libxml2 我已经下载了最新版本 2 7 7
  • MSMQ接收和删除

    是否有任何选项可以在读取消息后将其从 MSMQ 中删除 比如 接收 删除可以作为原子操作运行吗 听起来您想查看下一条消息 然后在处理完成后接收它 Message message Queue Peek Queue ReceiveById me
  • 以下 PLINQ 代码没有改进

    我没有看到使用以下代码的处理速度有任何改进 IEnumerable
  • 虚拟并行端口模拟器

    在我的计算机网络课程中 我们应该通过使用本机寄存器 例如使用 outportb 等命令 来学习并行端口编程 我没有并行端口 因为我住在 2011 年 但想练习这些程序 我使用 dosbox 安装了旧的 Turboc 3 IDE 有没有一个程
  • 关闭整数的最右边设置位

    我只需要关闭最右边的设置位即可 我的方法是找到最右边位的位置 然后离开该位 我编写这段代码是为了这样做 int POS int n int p 0 while n if n 2 0 p else break n n 2 return p i
  • 判断串口是普通COM还是SPP

    我正在寻找一种方法来确定 COM 是标准 COM 还是 SPP COM 也称为 COM 设备的电缆替换蓝牙适配器 我有一个可以在 USB COM gt USB 和蓝牙下工作的设备 并且蓝牙接口可以与 SPP 一起工作 我目前正在使用Syst
  • C 类型命名约定,_t 或 ALLCAPS

    我一直想知道是否有任何命名约定 例如何时对类型使用全部大写以及何时追加 t 什么时候不使用任何东西 我知道当时 K R 发布了各种有关如何使用 C 的文档 但我找不到任何相关内容 在 C 标准库类型中 t看起来漂亮占主导地位 time t
  • 名称查找、实例化点 (POI) 和基本类型

    以下代码针对 X 进行编译 但不适用于 double struct X void foo double void foo X namespace NN struct A void foo A foo double error foo not
  • 编写具有多种类型的泛型扩展方法时的类型推断问题

    我正在为 IEnumerable 编写一个通用扩展方法 用于将对象列表映射到另一个映射对象列表 这就是我希望该方法的工作方式 IList
  • 将 2 个字节转换为整数

    我收到一个 2 个字节的端口号 最低有效字节在前 我想将其转换为整数 以便我可以使用它 我做了这个 char buf 2 Where the received bytes are char port 2 port 0 buf 1 port
  • MSChart 控件中的自定义 X/Y 网格线

    我有一个带有简单 2D 折线图的 C Windows 窗体 我想向其中添加自定义 X 或 Y 轴标记 并绘制自定义网格线 例如 以突出显示的颜色 虚线 我查看了 customLabels 属性 但这似乎覆盖了我仍然想显示的默认网格 这是为了
  • 选择 asp.net CheckBoxList 中的所有项目

    ASP NET 和 C 我想要一个带有 全选 项目的复选框列表 当这个特定项目是 已选择 所有其他都将被选择 也 当选择被删除时 这个项目 也将来自所有人 其他物品 选中 取消选中 任何其他项目只会有一个 对特定项目的影响 无论选择状态如何
  • 在 mvc4 中创建通用 mvc 视图

    我以前也提过类似的问题 没有得到答案 如何创建一个通用的 mvc4 视图 该视图可以显示传递给它的模型列表或单个模型 模型可以是个人 组织或团体 无论传递给它的是什么 如果您正在寻找类似的东西 model MyViewModel
  • WPF DataGrid - 在每行末尾添加按钮

    我想在数据网格的每一行的末尾添加一个按钮 我找到了以下 xaml 但它将按钮添加到开头 有人知道如何在所有数据绑定列之后添加它吗 这会将按钮添加到开头而不是末尾
  • 将日期时间显示为 MM/dd/yyyy HH:mm 格式 C#

    在数据库中 日期时间以 MM dd yyyy HH mm ss 格式存储 但是 我想以 MM dd yyyy HH mm 格式显示日期时间 我通过使用 String Format 进行了尝试 txtCampaignStartDate Tex
  • 与 Entity Framework Core 2.0 的一对零关系

    我正在使用 C 和 NET Framework 4 7 将 Entity Framework 6 1 3 Code First 库迁移到 Entity Framework Core 我一直在用 Google 搜索 Entity Framew
  • 当 Verb="runas" 时设置 ProcessStartInfo.EnvironmentVariables

    我正在开发一个 C 应用程序 我需要创建变量并将其传递给新进程 我正在使用ProcessStartInfo EnvironmentVariables 新进程必须提升运行 因此我使用 Verb runas var startInfo new
  • 在 C 中使用 #define 没有任何价值

    If a define没有任何价值地使用 例如 define COMMAND SPI 默认值是0吗 不 它的评估结果为零 从字面上看 该符号被替换为空 然而 一旦你有了 define FOO 预处理器条件 ifdef FOO现在将是真的 另

随机推荐