Python 查找叉积以查找MatplotLib中直线上方/下方的点

Python 查找叉积以查找MatplotLib中直线上方/下方的点,python,matplotlib,Python,Matplotlib,我试图在MatPlotLib中绘制一条线,并根据坡度查找线上方或下方的所有点 在阅读了这篇文章,以及交叉积之后,我相信这是我检查要点的最好方法 我不确定在python中实现这一点的最佳方式是什么 v1 = {x2-x1, y2-y1} # Vector 1 v2 = {x2-xA, y2-yA} # Vector 2 xp = v1.x*v2.y - v1.y*v2.x # Cross product 有没有人尝试过实现类似的东西 是否有其他方法可以确定绘图上的点是否位于MatPlo

我试图在MatPlotLib中绘制一条线,并根据坡度查找线上方或下方的所有点

在阅读了这篇文章,以及交叉积之后,我相信这是我检查要点的最好方法

我不确定在python中实现这一点的最佳方式是什么

v1 = {x2-x1, y2-y1}   # Vector 1
v2 = {x2-xA, y2-yA}   # Vector 2
xp = v1.x*v2.y - v1.y*v2.x  # Cross product
有没有人尝试过实现类似的东西

是否有其他方法可以确定绘图上的点是否位于MatPlotLib中某条直线的上方或下方?

如在叉积中所示,确实可以用于确定点是否位于由两点定义的直线的上方或下方

因此,假设
a
b
是定义直线的两个点,以及
p
a(一组)点,我们想知道该点相对于直线的相对位置。那么如果

numpy.cross(p-a, b-a) < 0

肮脏的方法-使用带叉积()的左/右方法,然后计算直线的坡度。如果坡度为负,则直线左侧的任何点位于直线上方,如果坡度为正,则直线左侧的任何点位于直线下方。如果该点向右,则这些点会反转。(很明显,答案取决于y轴的方向,例如,我的示例“向上”为负,“向下”为正。)此方法需要对垂直线和水平线的特殊情况进行编程。对于水平线,叉积方法将给出点在线上方的位置。对于垂直线,没有真正的答案,但我们指向IsLeftOffline

C++代码:

bool Point::isLeftOfLine(Line cmp)
{
    return ((cmp.p2.x - cmp.p1.x) * (y - cmp.p1.y) > (cmp.p2.y - cmp.p1.y) * (x - cmp.p1.x));
}

bool Point::isTopOfLine(Line cmp)
{
    if(cmp.p1.x == cmp.p2.x || cmp.p1.y == cmp.p2.y)
    {
        return isLeftOfLine(cmp);
    }
return isLeftOfLine(cmp) == cmp.slope() < 0;
}

double Line::slope()
{
    return (p2.y - p1.y) / (p2.x - p1.x);
}
bool点::isLeftOfLine(行cmp)
{
返回((cmp.p2.x-cmp.p1.x)*(y-cmp.p1.y)>(cmp.p2.y-cmp.p1.y)*(x-cmp.p1.x));
}
布尔点::isTopOfLine(线cmp)
{
if(cmp.p1.x==cmp.p2.x | | cmp.p1.y==cmp.p2.y)
{
返回isLeftOfLine(cmp);
}
return isLeftOfLine(cmp)==cmp.slope()<0;
}
双线::坡度()
{
返回值(p2.y-p1.y)/(p2.x-p1.x);
}

请看第一部分。基本上,如果你有一个
x-y
对,你将
x
值插入到你的直线方程中,说
y1=a+b*x
,然后将结果与你的
y
值进行比较,也就是说,如果
y1>y
,则点在直线下方,如果回答得很好,特别是如果你确实想知道点
p
是方向
a->b
的直线的左边还是右边。但是,如果想要严格了解点是否在直线上方或下方(即,在给定的
x
下,大于或小于
y
值),与直线方程相比,仍然简单得多,因为对于叉积,您仍然需要一个
if
子句来测试直线的方向。@Thomas您可以简单地确保点
a
的x坐标小于
b
的x坐标,即沿x轴对点进行排序。这将自动确保“高于”意味着“高于”。哪种解决方案更简单的问题可能更多地取决于你从什么开始。如果有两个点定义了直线,则叉积是更好的解决方案,如果有斜率和y截距,则根据相对于直线的y坐标进行比较,如中所示。当然,每一个都可以从另一个计算出来。嗯,对
x
值进行排序很好。如果你有很多观点的话,我还得决定哪种计算更有效。当然,
np.cross
函数使代码看起来非常整洁,可能也很快…@Thomas直觉上我会说计算直线方程更快,至于
n
点,它涉及
n
乘法和
n
比较。叉积包括
2n
乘法和
n
比较。
bool Point::isLeftOfLine(Line cmp)
{
    return ((cmp.p2.x - cmp.p1.x) * (y - cmp.p1.y) > (cmp.p2.y - cmp.p1.y) * (x - cmp.p1.x));
}

bool Point::isTopOfLine(Line cmp)
{
    if(cmp.p1.x == cmp.p2.x || cmp.p1.y == cmp.p2.y)
    {
        return isLeftOfLine(cmp);
    }
return isLeftOfLine(cmp) == cmp.slope() < 0;
}

double Line::slope()
{
    return (p2.y - p1.y) / (p2.x - p1.x);
}