正如我们在图像中看到的那样,直线(由给定角度和计算中位数定义)远离将两个相等的部分分开。该线应该将x轴更多地向右切割,因为现在只有~25个点位于线的左侧,而~55个点位于右侧。
我已经知道了,我必须使用该点的角度进行中位数计算。
我计算中位数的第一种方法是将所有点旋转给定角度,然后将它们的角度用于x轴,但这显然是不够的。
我没有具体地坚持我必须应用于这一点的转换才能获得正确的中位数计算,所以任何帮助/提示都会受到赞赏,
非常感谢。
答案 0 :(得分:0)
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 [(不包括这些值)
编辑:奇数和偶数点数的两个例子:
代码(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)));