我有一条小船在横断面上移动,寻找动物。有人站在船的顶部,朝向前方,并且当看到动物时,正从船的前方记录距离船的距离。我有这个信息以及在看到动物的地方的船的xy坐标。 我需要根据这些信息获取动物本身的xy坐标。
我没有船的原始罗盘轴承,这使得这很棘手;但我所拥有的是船的下一个GPS(xy)坐标,我可以从中计算起始角度。由此,应该可以增加或减去看到动物的方位角以给出归一化角度,该角度可用于使用三角法找到动物的xy坐标。不幸的是,我的数学技能并不适合这项工作。
我有几百分,所以我需要将它放入Python脚本中以完成所有要点。
总之,数据集包含:
原稿X,原稿Y,结束(下一个)X,结束(下一个)Y,轴承,距离
编辑:对不起,我很匆忙,并没有很好地解释这一点。我发现这个问题有三个阶段。
我原来的Python代码如下所示,虽然它没什么用处 - 给出的数字就是例子。
distFromBoat = 100
bearing = 45
lengthOpposite = origX-nextX
lengthAdjacent = origY - nextY
virtX = origX #virtual X
virtY = origY-lengthOpposite #virtual Y
angle = math.degrees(math.asin(math.radians((lengthOpposite/transectLen))))
newangle = angle + bearing
newLenAdj = math.cos(newangle)*distFromBoat
newLenOpp = math.sqrt(math.pow(distFromBoat,2) + math.pow(newLenAdj,2) - 2*(distFromBoat*newLenAdj)*(math.cos(newangle)))
newX = virtX-newLenOpp
newY = origY-newLenAdj
print str(newX) +"---"+str(newY)
提前感谢您的帮助!
答案 0 :(得分:3)
Matt的功能有点问题,所以我使用atan2
来确定船的角度。
编辑:这比我想象的要复杂得多。最后,您需要减去90并采用反转从地理参考角度到三角形角度。
(还有一个angles
库(可能还有其他地理位置的库)。
现在这需要origX
和origY
,找到三角形并将其转换为heading
,将轴承添加到为横断面确定的角度。然后它会对距离进行触发,但使用转换回三角度-(X-90)
的角度。它有点扭曲,因为我们习惯于将0
度视为北/上,但是在三角形中它是"到右边",而trig则逆时针方向与顺时针方向相反以进行导航。
import math
origX = 0.0
origY = 0.0
nextX = 0.0
nextY = -1.0
distance = 100.0
bearing = 45
def angle(origX,origY,nextX,nextY):
opp = float(nextY - origY)
adj = float(nextX - origX)
return(math.degrees(math.atan2(adj,opp)))
# atan2 seems to even work correctly (return zero) when origin equals next
transectAngle = angle(origX,origY,nextX,nextY) # assuming the function has been defined
print "bearing plus trans", transectAngle + bearing
trigAngle = -(transectAngle + bearing -90)
print "trig equiv angle", trigAngle
newX = origX + distance * math.cos(math.radians(trigAngle))
newY = origY + distance * math.sin(math.radians(trigAngle))
print "position",newX,newY
输出:
-70.7106781187 -70.7106781187
这是打印出一堆测试用例的函数(使用全局变量,因此应该折叠到上面的代码中)
def testcase():
bearinglist = [-45,45,135,-135]
dist = 10
for bearing in bearinglist:
print "----transect assuming relative bearing of {}------".format(bearing)
print "{:>6} {:>6} {:>6} {:>6} {:>6} {:>6} {:>6} {:>6}".format("x","y","tran","head","trigT","trigH","newX","newY")
for x in [0,.5,-.5]:
for y in [0,.5,1,-.5]:
# print "A:", x,y,angle(origX,origY,x,y)
tA = newangle(origX,origY,x,y)
trigA = -(tA-90)
heading = tA + bearing
trigHead = -(heading-90)
Xnew = distance * math.cos(math.radians(trigHead))
Ynew = distance * math.sin(math.radians(trigHead))
print "{:>6.1f} {:>6.1f} {:>6.1f} {:>6.1f} {:>6.1f} {:>6.1f} {:>6.1f} {:>6.1f}".format(x,y,tA,heading,trigA,trigHead,Xnew,Ynew)
答案 1 :(得分:2)
根据我的理解,这是你的问题:
start
和next
,您正在New
的坐标,该距离与start
相距一定距离,因为您已经面临start
到next
}。我的解决方案是:
start
到next
start
start
视为向量,添加的结果是您的新观点因为逆时针旋转("从当前点开始离开")被认为是正数,所以您需要反转bearing
以使该端口与负值相关联,并且右舷与正值相关联。 / p>
<强>代码强>
import math
origX = 95485
origY = 729380
nextX = 95241
nextY = 729215
distance = 2000.0
bearing = 45
origVec = origX, origY
nextVec = nextX, nextY
#Euclidean distance between vectors (L2 norm)
dist = math.sqrt((nextVec[0] - origVec[0])**2 + (nextVec[1] - origVec[1])**2)
#Get a normalized difference vector
diffVec = (nextVec[0] - origVec[0])/dist, (nextVec[1] - origVec[1])/dist
#rotate our vector by bearing to get a vector from orig towards new point
#also, multiply by distance to get new value
#invert bearing, because +45 in math is counter-clockwise (left), not starboard
angle = math.radians(-bearing)
newVec = origVec[0]+(diffVec[0]*math.cos(angle) - diffVec[1]*math.sin(angle))*distance, \
origVec[1]+(diffVec[0]*math.sin(angle) + diffVec[1]*math.cos(angle))*distance
print newVec
<强>输出:强>
(93521.29597031244,729759.2973553676)
答案 2 :(得分:0)
这可能(可能)有一个比这更优雅的解决方案...假设我正确理解你的问题。但是,这将使您从原始位置获得影响:
(输入硬编码为例)
import math
origX = 0.0
origY = 0.0
nextX = 1.0
nextY = 0.0
Dist = ((nextX - origX)**2 + (nextY - origY)**2)**0.5
if origX == nextX and origY == nextY:
angle = 0
if origX == nextX and nextY < origY:
angle = 180
if nextY < origY and origX > nextX:
angle = math.degrees(math.asin((nextX -origX)/Dist)) - 90
if nextX > origX and nextY < origY:
angle = math.degrees(math.asin((nextX -origX)/Dist)) + 90
else:
angle = math.degrees(math.asin((nextX -origX)/Dist))
print angle