你好,第一部分就像魅力一样,谢谢大家。
但我还有另一个问题......
应该刷新页面CodeMonkey解决方案正是我所寻找的......
再次感谢你。
============================
首先,我不是开发人员,我是一个简单的木工,太早离开学校......
我正在努力使我的工具之一与自动机器人一起工作。 我通过阅读很多教程让他们沟通。
但我有一个问题我无法弄明白。
机器人期望工具的位置为(X,Y),但工具的输出为(A,B,C) A是工具到北方的距离 B到东方的距离 C轴距离东轴顺时针120度
边界是圆形,半径可能会改变,可能是也可能不是我所知道的。
我已经持续了1个月,我找不到将这些价值转化为这个位置的方法。
我在一个圆圈上用3个钉子做了一个测试我画在木头上,如果我有距离,那么只有一个位置可能,所以我猜它可能。 但是如何?
另外,如果有人作为答案我喜欢伪代码而不是代码,所以我可以练习。
如果有工具可以制作图纸,我可以用它来说清楚它可以指出给我吗?
谢谢。
希望它有所帮助:X,Y是中心坐标,Da,Db,Dc是已知的。
试图让它更清晰(抱歉它在我脑海中如此清晰)。
X,Y是工具(P)所在点的坐标。 中心位于0,0
A是垂直线从P切割圆的点,Da距离P为A;
B是水平线切割圆形P的点,Db距离P为B.
C是从水平方向顺时针方向120处的线从P切割圆的点,Dc距离P为C。
工具输出是一个int数组(单位mm):A = 123,B = 114,C = 89 这些是我唯一的信息
感谢我以后在家尝试的所有想法, 希望它有效:)
答案 0 :(得分:2)
基本几何。我决定放弃原点的圆圈。我们还不知道圆圈的中心。你拥有的是该圈子上的三个点。让我们尝试将工具的位置(以P给出)作为新的(0,0)。因此,这解决了找到给出三个点的圆:(0,Da); (Db,0),并在Dc距离处以120°后退。
伪代码:
由于P位于(0,0),圆的原点的负数将是工具相对于圆的原点的坐标。你现在应该可以计算出你需要的任何东西了。
两点之间的中点:X =(X1 + X2)/ 2。 Y =(Y1 + Y2)/ 2。
可以使用例如圆计算圆的半径。 A点和圆的起源:R = sqrt(sqr((Ax-CirX)+ sqr(Ay-CirY))
距边缘的距离:圆的半径 - 工具再次通过毕达哥拉斯定理与圆心的距离。
答案 1 :(得分:1)
你的问题是一个“限定的圈子”。你有一个三角形,从机器人位置以给定角度定义3个距离,然后你可以从这三个点构造外接圆(见Circumscribed circle from Wikipedia - section "Other properties")。所以你知道直径(如果需要的话)。
众所周知,三角形边的垂直二等分的交汇点是外接圆的中心。
答案 2 :(得分:1)
我们a=Da, b=Db
。我们可以在圆周上为A点和B点编写一个系统:
(x+b)^2 + y^2 = r^2
(y+a)^2 + x^2 = r^2
转换后我们有二次方程
y^2 * (4*b^2+4*a^2) + y * (4*a^3+4*a*b^2) + b^4-4*b^2*r^2+a^4+2*a^2*b^2 = 0
or
AA * y^2 + BB * y + CC = 0
where coefficients are
AA = (4*b^2+4*a^2)
BB = (4*a^3+4*a*b^2)
CC = b^4-4*b^2*r^2+a^4+2*a^2*b^2
因此计算AA,BB,CC系数,找到二次方程的解y1,y2,然后使用
得到相应的x1,x2值 x = (a^2 - b^2 + 2 * a * y) / (2 * b)
并选择真实解对(其中坐标在圆内)
快速检查:
a=1,b=1,r=1
按预期提供坐标0,0
(并在圆圈外显示假1,-1
)
a=3,b=4,r=5
在图片中给出了坐标(粗略)0.65, 1.96
,距离大约为3和4。
Delphi代码(不检查所有可能的错误)输出x: 0.5981 y: 1.9641
var
a, b, r, a2, b2: Double;
aa, bb, cc, dis, y1, y2, x1, x2: Double;
begin
a := 3;
b := 4;
r := 5;
a2 := a * a;
b2:= b * b;
aa := 4 * (b2 + a2);
bb := 4 * a * (a2 + b2);
cc := b2 * b2 - 4 * b2 * r * r + a2 * a2 + 2 * a2 * b2;
dis := bb * bb - 4 * aa * cc;
if Dis < 0 then begin
ShowMessage('no solutions');
Exit;
end;
y1 := (- bb - Sqrt(Dis)) / (2 * aa);
y2 := (- bb + Sqrt(Dis)) / (2 * aa);
x1 := (a2 - b2 + 2 * a * y1) / (2 * b);
x2 := (a2 - b2 + 2 * a * y2) / (2 * b);
if x1 * x1 + y1 * y1 <= r * r then
Memo1.Lines.Add(Format('x: %6.4f y: %6.4f', [x1, y1]))
else
if x2 * x2 + y2 * y2 <= r * r then
Memo1.Lines.Add(Format('x: %6.4f y: %6.4f', [x2, y2]));
答案 3 :(得分:1)
假设你知道X和Y.R是圆的半径。
|(X, Y + Da)| = R
|(X + Db, Y)| = R
|(X - cos(pi/3) * Dc, Y - cos(pi/6) * Dc)| = R
假设我们不知道半径R.我们仍然可以说
|(X, Y + Da)|^2 = |(X + Db, Y)|^2
=> X^2 + (Y+Da)^2 = (X+Db)^2 + Y^2
=> 2YDa + Da^2 = 2XDb + Db^2 (I)
并将cos(pi / 3)* Dc表示为c1和cos(pi / 6)* Dc表示为c2:
|(X, Y + Da)|^2 = |(X - c1, Y - c2)|^2
=> X^2 + Y^2 + 2YDa + Da^2 = X^2 - 2Xc1 + c1^2 + Y^2 - 2Yc2 + c2^2
=> 2YDa + Da^2 = - 2Xc1 + c1^2 - 2Yc2 + c2^2
=> Y = (-2Xc1 + c1^2 + c2^2 - Da^2) / 2(c2+Da) (II)
将(II)放回等式(I)中我们得到:
=> (-2Xc1 + c1^2 + c2^2 - Da^2) Da / (c2+Da) + Da^2 = 2XDb + Db^2
=> (-2Xc1 + c1^2 + c2^2 - Da^2) Da + Da^2 * (c2+Da) = 2XDb(c2+Da) + Db^2 * (c2+Da)
=> (-2Xc1 + c1^2 + c2^2) Da + Da^2 * c2 = 2XDb(c2+Da) + Db^2 * (c2+Da)
=> X = ((c1^2 + c2^2) Da + Da^2 * c2 - Db^2 * (c2+Da)) / (2Dbc2 + 2Db*Da + 2Dac1) (III)
知道X,你可以通过计算(II)得到Y.
您还可以进行一些简化,例如c1 ^ 2 + c2 ^ 2 = Dc ^ 2
将它放入Python(几乎是伪代码):
import math
def GetXYR(Da, Db, Dc):
c1 = math.cos(math.pi/3) * Dc
c2 = math.cos(math.pi/6) * Dc
X = ((c1**2 + c2**2) * Da + Da**2 * c2 - Db * Db * (c2 + Da)) / (2 * Db * c2 + 2 * Db * Da + 2 * Da * c1)
Y = (-2*X*c1 + c1**2 + c2**2 - Da**2) / (2*(c2+Da))
R = math.sqrt(X**2 + (Y+Da)**2)
R2 = math.sqrt(Y**2 + (X+Db)**2)
R3 = math.sqrt((X - math.cos(math.pi/3) * Dc)**2 + (Y - math.cos(math.pi/6) * Dc)**2)
return (X, Y, R, R2, R3)
(X, Y, R, R2, R3) = GetXYR(123.0, 114.0, 89.0)
print((X, Y, R, R2, R3))
我得到的结果(X,Y,R,R2,R3)=(-8.129166703588021,-16.205081335032794,107.1038654949096,107.10386549490958,107.1038654949096)
如果Da和Db都比Dc长,那么这似乎是合理的,那么两个坐标都可能是负的。
我从三个方程计算出半径,以交叉检查我的计算是否有意义。它似乎满足了我们在开始时设置的所有三个方程式。
答案 4 :(得分:0)
从您的图表中,您需要点P
,X
&amp; Y
坐标。因此,我们需要找到Px
和Py
或(Px,Py)
。我们知道Ax = Px
和By = Py
。如果需要,我们可以使用它们进行替换。我们知道C
&amp; P
创建一条线,所有线条都以y = mx + b
的形式出现斜率。斜率为m
且y截距为b
的位置。我们此时不知道m
或b
,但可以找到它们。我们知道向量为CP
和PB
的两个向量之间的角度给出了120°
的角度,但这并没有将角度置于标准位置,因为这是一个{{ 1}}旋转。当使用圆和触发函数以及其中的斜率线性方程时,最好以标准形式工作。因此,如果此CW
行显示点y = mx + b
&amp; C
属于水平线上方与水平轴平行的角度,该水平轴由点P
&amp; P
将是B
我们也知道两个向量之间的角度也等于这些向量的点积除以它们的大小的乘积。
我们还没有确切的数字,但我们可以构造一个公式:由于theta = 180° - 120° = 60°
高于标准位置的水平线,我们知道斜率60°
也是该角度的正切值;所以这条线的斜率是棕褐色(60°)。那么让我们回到线性方程m
。由于y = tan(60°)x + b
是b
拦截,我们需要在y
等于x
时找到y
。由于我们仍然有三个未定义的变量0
,y
和x
,我们可以使用此行上的点来帮助我们。我们知道点b
&amp; C
就在这条线上。因此P
的这个向量是由y = tan(60°)x + b
构造的。然后向量是(Px, Py) - (Cx, Cy)
,其水平线上方的(Px-Cx, Py-Cy)
角度与水平轴平行。我们需要使用另一种形式的线性方程,这个方程涉及此时的点和斜率恰好是60°
所以这就变成y - y1 = m(x - x1)
我之前说过我们可以替代,所以让我们继续然后执行此操作:y - Py = tan(60°)(x - Px)
然后y - By = tan(60°)(x - Ax)
。如果您知道y - By = tan(60°)x - tan(60°)Ax
&amp;的实际坐标点,就会知道这一点。 A
。这里唯一的事情是您必须将B
的角度转换为标准形式。这完全取决于你的已知和未知数。因此,如果您需要120°
并且您同时拥有P
&amp;从图表中可以看出A
工作很简单,因为B
所需的点数为P
。既然你已经说过你知道P(Ax,By)
,Da
&amp; Db
长度只需要用正确的角度应用正确的三角函数,或者用毕达哥拉斯定理来找到三角形另一条腿的长度。从其他观点找到Dc
的内容应该不是那么难。你可以使用三角函数,线性方程,毕达哥拉斯定理,向量计算等。如果你能找到指向P(x,y)
&amp;的线的方程。 C
知道P
具有P
A's
值且x
B's
值且具有由切线定义的该线的斜率水平线上方是y
,其中180° - phi
是你给出的phi
旋转角度,而CW
是标准位置或水平线以上的角度theta
的一般形式,从这个等式中你可以找到该行的任何一点。
还有其他方法,比如使用现有的点和彼此之间创建的向量,然后使用这些点生成等边三角形,然后从等边生成一个,如果可以生成一个,则可以使用它的垂直平分线三角形找到那个三角形的质心。这是另一种可以做到的方法。您可能需要考虑的唯一事情是从原点线的线性平移。因此,您将在(Ax - origin,By - origin)的行中进行移位,并找到一个将另一个设置为0,反之亦然。有很多不同的方法可以找到它。
我刚刚向您展示了几种数学技巧,可以帮助您根据已知的和未知的方法找到一个通用的方程式。只需要识别哪个方程式适用于哪种情况。一旦你认识到正确的方程式;其余的相当容易。我希望这可以帮助你。
编辑
我忘了提一件事;这就是y - By = tan(180° - phi)(x - Ax)
的一行在第一象限中由CP
定义的圆的边缘上有一个点。在第三个象限中,您将在此行上有一个点,(cos(60°), sin(60°))
定义的圆圈表示此行经过原点(-cos(60°), -sin(60°))
,其中没有(0,0)
或y
拦截,如果是这种情况,那么任何一端的圆上的点和原点都将是该圆的半径。