根据给定角度计算点的中位数

时间:2015-05-06 15:21:25

标签: math geometry

我正在编程一棵树来划分二维空间。 因此,我需要根据给定的角度将当前的点集分成两个相等的部分。所以下面附图中的黑线经过计算出的中位数。

正如我们在图像中看到的那样,直线(由给定角度和计算中位数定义)远离将两个相等的部分分开。该线应该将x轴更多地向右切割,因为现在只有~25个点位于线的左侧,而~55个点位于右侧。

我已经知道了,我必须使用该点的角度进行中位数计算。

我计算中位数的第一种方法是将所有点旋转给定角度,然后将它们的角度用于x轴,但这显然是不够的。

我没有具体地坚持我必须应用于这一点的转换才能获得正确的中位数计算,所以任何帮助/提示都会受到赞赏,

非常感谢。

Not working

1 个答案:

答案 0 :(得分:0)

Normal form of line equation

x * Cos(Theta) + y * Sin(Theta) - p = 0

其中

Theta = Pi/2 + Fi 

Fi是你给定的角度 您必须找到适当的p值才能将点集划分为两个相等的部分。

签名distance from this line to point Q

D = Q.X * Cos(Theta) + Q.Y * Sin(Theta) - p

按D [i]值对点阵数进行排序并找到中位数 如果点数为奇数,则将D [中位数]作为线性方程的p,否则可以选择D [leftmedian]和D [rightmedian]之间的任何p值

示例:
5点,D =( - 3,-1,4,5,8) - 得到p = 4(线穿过一点)
6分,D =( - 3,-1,2,5,7,9) - 得到任何p在范围内] 2..5 [(不包括这些值)

编辑:奇数和偶数点数的两个例子:

enter image description here enter image description here

代码(Delphi):

var
  Pt: TArray<TPoint>;
  D: TArray<Double>;
  N, i: Integer;
  Fi, Theta, p: Double;
begin
  Randomize;
  N := 7 + Random(2); // number of points, 7 or 8
  Fi := Pi / 4;   //line slope angle
  Theta := Pi / 2 + Fi;
  SetLength(Pt, N);   //point cloud
  SetLength(D, N);    //distance params
  Canvas.FillRect(ClientRect);

  //generate random points and draw them
  for i := 0 to N - 1 do begin
    Pt[i] := Point(Random(400), Random(400));
    Canvas.Rectangle(Pt[i].X - 2, Pt[i].Y - 2, Pt[i].X + 3, Pt[i].Y + 3);
  end;

  //fill param array
  for i := 0 to N - 1 do
    D[i] := Pt[i].X * Cos(Theta) + Pt[i].Y * Sin(Theta);

  //sort distance parameters
  TArray.Sort<Double>(D);

  //get line parameter as median of array
  if Odd(N) then
    p := D[N div 2]
  else
    p := (D[N div 2 - 1] + D[N div 2]) / 2;

  //draw calculated line
  Canvas.MoveTo(0, Round(p / Sin(Theta)));
  Canvas.LineTo(500, Round((p - 500 * Cos(Theta)) / Sin(Theta)));