根据给定距离移动xy坐标并从横断面移动

时间:2014-03-26 17:20:49

标签: python coordinates

我有一条小船在横断面上移动,寻找动物。有人站在船的顶部,朝向前方,并且当看到动物时,正从船的前方记录距离船的距离。我有这个信息以及在看到动物的地方的船的xy坐标。 我需要根据这些信息获取动物本身的xy坐标。

我没有船的原始罗盘轴承,这使得这很棘手;但我所拥有的是船的下一个GPS(xy)坐标,我可以从中计算起始角度。由此,应该可以增加或减去看到动物的方位角以给出归一化角度,该角度可用于使用三角法找到动物的xy坐标。不幸的是,我的数学技能并不适合这项工作。

我有几百分,所以我需要将它放入Python脚本中以完成所有要点。

总之,数据集包含:

原稿X,原稿Y,结束(下一个)X,结束(下一个)Y,轴承,距离

编辑:对不起,我很匆忙,并没有很好地解释这一点。

我发现这个问题有三个阶段。

  1. 找到横断面的原始方位
  2. 找到相对于样带的点的方位
  3. 根据此标准化角度和距离船只开始的距离xy找到点的新坐标
  4. 我原来的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)
    

    提前感谢您的帮助!

3 个答案:

答案 0 :(得分:3)

Matt的功能有点问题,所以我使用atan2来确定船的角度。

编辑:这比我想象的要复杂得多。最后,您需要减去90并采用反转从地理参考角度到三角形角度。

(还有一个angles库(可能还有其他地理位置的库)。

现在这需要origXorigY,找到三角形并将其转换为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)

enter image description here adding paths

答案 1 :(得分:2)

根据我的理解,这是你的问题:

  • 您有2分,startnext,您正在
  • 之间行走
  • 您希望找到第三个点New的坐标,该距离与start相距一定距离,因为您已经面临startnext }。

我的解决方案是:

  • 创建从startnext
  • 的规范化向量
  • 通过给定方位旋转您的标准化矢量
  • 将规范化的旋转矢量乘以距离,然后将其添加到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