English 中文(简体)
如何说明某一点是右线还是左边
原标题:How to tell whether a point is to the right or left side of a line

我有一套看法。 我想将其分成两套。 为此,我选择两点(ab),并在两点之间划出一条想象线。 现在,我想在一行中留下所有要点,在另一组中,这些要点是正确的。

我怎么能够告诉任何特定问题z。 是否在左边或右边? 我试图计算a-z-b之间的角角——小于180的角逐右侧,左侧超过180度——但由于ArcCos的定义,计算出来的角一直小于180°。 是否有一个公式来计算角值大于180°(或选择右边或左边的任何其他公式)?

最佳回答

利用矢量分析符号<>(AB,AM),M(X,Y) 问题是:

position = sign((Bx - Ax) * (Y - Ay) - (By - Ay) * (X - Ax))

http://code>0 on the line, and +1 on oneside,-1>.

问题回答

你看一看 determinant的标志

| x2-x1  x3-x1 |
| y2-y1  y3-y1 |

这对一方而言是积极的,对另一方而言是消极的(对线上各点而言是零)。

病媒代码<>(y1 - y2, x2 - x1)是按行程排列的,总是指点正确(或者总是指点左,如果您的定位与地雷不同)。

然后,你可以计算该矢量和<代码>(x3 - x1, y3 - y1)的直线产品,以确定该点是否与单体矢量(代特产品与特;0)相同。

我在java进行了试验(资料来源如下)。 上述解决办法均未奏效。 该法典通过单位测试。 如果有人发现一个没有经过的单位试验,请让我知道。

编码:nearlyEqual(双重、双重),如果两个数字非常接近,即为回报。

/*
 * @return integer code for which side of the line ab c is on.  1 means
 * left turn, -1 means right turn.  Returns
 * 0 if all three are on a line
 */
public static int findSide(
        double ax, double ay, 
        double bx, double by,
        double cx, double cy) {
    if (nearlyEqual(bx-ax,0)) { // vertical line
        if (cx < bx) {
            return by > ay ? 1 : -1;
        }
        if (cx > bx) {
            return by > ay ? -1 : 1;
        } 
        return 0;
    }
    if (nearlyEqual(by-ay,0)) { // horizontal line
        if (cy < by) {
            return bx > ax ? -1 : 1;
        }
        if (cy > by) {
            return bx > ax ? 1 : -1;
        } 
        return 0;
    }
    double slope = (by - ay) / (bx - ax);
    double yIntercept = ay - ax * slope;
    double cSolution = (slope*cx) + yIntercept;
    if (slope != 0) {
        if (cy > cSolution) {
            return bx > ax ? 1 : -1;
        }
        if (cy < cSolution) {
            return bx > ax ? -1 : 1;
        }
        return 0;
    }
    return 0;
}

单位测试:

@Test public void testFindSide() {
    assertTrue("1", 1 == Utility.findSide(1, 0, 0, 0, -1, -1));
    assertTrue("1.1", 1 == Utility.findSide(25, 0, 0, 0, -1, -14));
    assertTrue("1.2", 1 == Utility.findSide(25, 20, 0, 20, -1, 6));
    assertTrue("1.3", 1 == Utility.findSide(24, 20, -1, 20, -2, 6));

    assertTrue("-1", -1 == Utility.findSide(1, 0, 0, 0, 1, 1));
    assertTrue("-1.1", -1 == Utility.findSide(12, 0, 0, 0, 2, 1));
    assertTrue("-1.2", -1 == Utility.findSide(-25, 0, 0, 0, -1, -14));
    assertTrue("-1.3", -1 == Utility.findSide(1, 0.5, 0, 0, 1, 1));

    assertTrue("2.1", -1 == Utility.findSide(0,5, 1,10, 10,20));
    assertTrue("2.2", 1 == Utility.findSide(0,9.1, 1,10, 10,20));
    assertTrue("2.3", -1 == Utility.findSide(0,5, 1,10, 20,10));
    assertTrue("2.4", -1 == Utility.findSide(0,9.1, 1,10, 20,10));

    assertTrue("vertical 1", 1 == Utility.findSide(1,1, 1,10, 0,0));
    assertTrue("vertical 2", -1 == Utility.findSide(1,10, 1,1, 0,0));
    assertTrue("vertical 3", -1 == Utility.findSide(1,1, 1,10, 5,0));
    assertTrue("vertical 3", 1 == Utility.findSide(1,10, 1,1, 5,0));

    assertTrue("horizontal 1", 1 == Utility.findSide(1,-1, 10,-1, 0,0));
    assertTrue("horizontal 2", -1 == Utility.findSide(10,-1, 1,-1, 0,0));
    assertTrue("horizontal 3", -1 == Utility.findSide(1,-1, 10,-1, 0,-9));
    assertTrue("horizontal 4", 1 == Utility.findSide(10,-1, 1,-1, 0,-9));

    assertTrue("positive slope 1", 1 == Utility.findSide(0,0, 10,10, 1,2));
    assertTrue("positive slope 2", -1 == Utility.findSide(10,10, 0,0, 1,2));
    assertTrue("positive slope 3", -1 == Utility.findSide(0,0, 10,10, 1,0));
    assertTrue("positive slope 4", 1 == Utility.findSide(10,10, 0,0, 1,0));

    assertTrue("negative slope 1", -1 == Utility.findSide(0,0, -10,10, 1,2));
    assertTrue("negative slope 2", -1 == Utility.findSide(0,0, -10,10, 1,2));
    assertTrue("negative slope 3", 1 == Utility.findSide(0,0, -10,10, -1,-2));
    assertTrue("negative slope 4", -1 == Utility.findSide(-10,10, 0,0, -1,-2));

    assertTrue("0", 0 == Utility.findSide(1, 0, 0, 0, -1, 0));
    assertTrue("1", 0 == Utility.findSide(0,0, 0, 0, 0, 0));
    assertTrue("2", 0 == Utility.findSide(0,0, 0,1, 0,2));
    assertTrue("3", 0 == Utility.findSide(0,0, 2,0, 1,0));
    assertTrue("4", 0 == Utility.findSide(1, -2, 0, 0, -1, 2));
}

我想提供由物理学启发的解决办法。

想象一支部队沿蓝线部署,你正在测量部队的频率。 如果频率是肯定的(贴现),那么点就是指线的“左”,但如果频率是负的,则点是线的“权利”。

因此,如果病媒的大小等于确定线的两点。

fx = x_2 - x_1
fy = y_2 - y_1

页: 1

var torque = fx*(py-y_1)-fy*(px-x_1)
if  torque>0  then
     "point on left side"
else if torque <0 then
     "point on right side"  
else
     "point on line"
end if

1. 如果你有垂直线,首先检查:

if (x2-x1) == 0
  if x3 < x2
     it s on the left
  if x3 > x2
     it s on the right
  else
     it s on the line

然后计算斜坡:m = (y2-y1)/(x2-x1)

然后,采用斜坡度表设定一条线的方程式:y - y1 = m*(x-x1)+1。 为了我的解释,将其简化为斜坡截面表(在你的算法中没有必要): <代码>y = mx+b。

如今,<代码>(x3, y3)>> 和<代码>y。 这里有一些伪装,详细说明了应当做些什么:

if m > 0
  if y3 > m*x3 + b
    it s on the left
  else if y3 < m*x3 + b
    it s on the right
  else
    it s on the line
else if m < 0
  if y3 < m*x3 + b
    it s on the left
  if y3 > m*x3+b
    it s on the right
  else
    it s on the line
else
  horizontal line; up to you what you do

假设这些要点是(Ax,Ay)(Bx,By)和(Cx,Cy),你需要赞扬:

(Bx - Ax) * (Cy - Ay) - (By - Ay) * (Cx - Ax)

如果C点位于A点和B点所形成线上,则该点等于零,并且视一方而有不同的信号。 哪一方取决于您(x,y)坐标的取向,但你可以将A、B和C的检验值推入这一公式,以确定消极价值是否属于左边还是属于右边。

基本上,我认为,对于任何特定的聚合物而言,解决办法非常容易和直截了当。 可以说,解决办法包括四个vert(第1页,第2页,第3页,第4页),在多角发现两个极端的对面vert,换言之,就是找到最左上层的vert(即第1页)和位于最底层的对面的vert(左)。 因此,鉴于您的C(x,y)测试点,现在你必须在C和P1、C和p4之间进行双重检查:

if cx > p1x AND cy > p1y ==> means that C is lower and to right of p1 next if cx < p2x AND cy < p2y ==> means that C is upper and to left of p4

最后,C处于困境。

感谢:

@AVB

det = Matrix[
  [(x2 - x1), (x3 - x1)],
  [(y2 - y1), (y3 - y1)]
].determinant

如果有的话,<代码>det即为上。 如果0,则按行。

这里的版本再次使用在Clojure书写的跨产品逻辑。

(defn is-left? [line point]
  (let [[[x1 y1] [x2 y2]] (sort line)
        [x-pt y-pt] point]
    (> (* (- x2 x1) (- y-pt y1)) (* (- y2 y1) (- x-pt x1)))))

例常使用:

(is-left? [[-3 -1] [3 1]] [0 10])
true

也就是说,点(0、10)是指由(-3、-1)和(3、1)。

注:这一执行解决了一个问题,即没有其他人(迄今为止)这样做! <>Order>在给出确定线标的时,请注明。 一、导 言 因此,按照上述代码,这一援引也产生<条码>true的结果:

(is-left? [[3 1] [-3 -1]] [0 10])
true

这是因为这部法典:

(sort line)

最后,与其他以产品为基础的解决方案一样,这一解决办法将是一种 b,没有给串通带来第三个结果。 但它将产生有意义的结果,例如:

(is-left? [[1 1] [3 1]] [10 1])
false

Issues with the existing solution:

尽管我发现埃里克·巴因维尔的答复是正确的,但我发现这完全不足以理解:

  • How can two vectors have a determinant? I thought that applied to matrices?
  • What is sign?
  • How do I convert two vectors into a matrix?

position = sign(Bx - Ax) * (Y - Ay) - (By - Ay) *(X-Ax)

  • What is Bx?
  • What is Y? Isn t Y meant to be a Vector, rather than a scalar?
  • Why is the solution correct - what is the reasoning behind it?

此外,我的使用案例涉及complex curves,而不是一条简单的一条线,因此,需要重新计算:

Reconstituted Answer

Point a = new Point3d(ax, ay, az); // point on line
Point b = new Point3d(bx, by, bz); // point on line

如果你想看到你的观点是否高于/低于curve,那么,你需要首先获得你感兴趣的特定曲线的衍生物——也称为曲线的精髓。 如果你能够这样做,那么你就可以强调你感兴趣的要点。 当然,如果你的曲线是一线,那么你就不需要兴趣,而没有实质意义。 深层的IS线。

Vector3d lineVector = curve.GetFirstDerivative(a); // where "a" is a point on the curve. You may derive point b with a simple displacement calculation:

Point3d b = new Point3d(a.X, a.Y, a.Z).TransformBy(
                 Matrix3d.Displacement(curve.GetFirstDerivative(a))
                );

Point m = new Point3d(mx, my, mz) // the point you are interested in.

The Solution:

return (b.X - a.X) * (m.Y - a.Y) - (b.Y - a.Y) * (m.X - a.X) < 0; // the answer

www.un.org/Depts/DGACM/index_spanish.htm 页: 1 见上文照片中的证明。 绿色砖满足了条件,但外的砖瓦被过滤! 在我使用的情况下,我只想起触动圈子的砖头。

“所有绿色物品都在曲线范围内”/

Theory behind the answer

我再作解释。 一天。 ......

了解网络提供的解决办法的另一个途径是了解一些地理分布影响。

<>pqr=[P,Q,R]是按<<>条/>分到2方的平面。 我们要指出,在<<>pqr plane, A,B”两点是否在同一方面。

在pqr plane上的任何T可使用2个病媒:v=P-Q和u=R-Q:

T = T-Q = i* 诉+j *

现在对地貌的影响:

  1. i+j =1: T on pr line
  2. i+j <1: T on Sq
  3. i+j >1: T on Snq
  4. i+j =0: T = Q
  5. i+j <0: T on Sq and beyond Q.

i+j: <0 0 <1 =1 >1 ---------Q------[PR]--------- <== this is PQR plane ^ pr line

总的来说,

  • i+j is a measure of how far T is away from Q or line [P,R], and
  • the sign of i+j-1 implicates T s sideness.

ij(与这一解决办法无关)的其他几何意义是:

  • i,j are the scalars for T in a new coordinate system where v,u are the new axes and Q is the new origin;
  • i, j can be seen as pulling force for P,R, respectively. The larger i, the farther T is away from R (larger pull from P).

可通过解决以下各点获得i,j:

i*vx + j*ux = T x
i*vy + j*uy = T y
i*vz + j*uz = T z

因此,我们得到了2点,A点,B点:

A = a1 * v + a2 * u B = b1 * v + b2 * u

如果A,B处于同一个一边,情况是:

sign(a1+a2-1) = sign(b1+b2-1)

注意这一点也适用于问题:Are A,B in the sameside of plane [P,Q,R, in which:

T =i * P + j * Q +k

i+j+k=1意味着T处于平面[P,Q,R],而i+j+k-1的标志意味着其副作用。 从这一点来看,我们已经:

A = a1 * P + a2 * Q + a3 * R B = b1 * P + b2 * Q + b3 * R

如果是,A、B和A与Pe[P,Q,R]的对应关系相同,

sign(a1+a2+a3-1) = sign(b1+b2+b3-1)

等距等于-y1 = m(x-x1)

页: 1

如今,将 m放在 equation子上,把 condition放在 y上;m(x-x1) + y1, 那么,它就留下了次要点。

例如。

for i in rows:

  for j in cols:

    if j>m(i-a)+b:

      image[i][j]=0

A(x1,y1) B(x2,y2)a行长L=sqrt(y2-y1)^2 +(x2-x1)^2

M.(x,y)

改变坐标,以便成为新开端的A点,成为新轴的B点

我们有M点的新坐标。

which are newX = ((x-x1)(x2-x1)+(y-y1)(y2-y1)) / L
from (x-x1)*cos(t)+(y-y1)*sin(t) where cos(t)=(x2-x1)/L, sin(t)=(y2-y1)/L

newY = ((y-y1)(x2-x1)-(x-x1)(y2-y1)) / L
from (y-y1)*cos(t)-(x-x1)*sin(t)

because "left" is the side of axis X where the Y is positive, if the newY (which is the distance of M from AB) is positive, then it is on the left side of AB (the new X axis) You may omit the division by L (allways positive), if you only want the sign





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签