在PyGame中绘制符合线条方向的箭头

时间:2017-04-20 19:06:05

标签: python python-2.7 pygame geometry algebra

在Pygame中,如果给定箭头的起点和终点,我如何计算箭头的三个点的坐标,以便箭头指向与线相同的方向?

def __draw_arrow(self, screen, colour, start, end):     
    start = self.__coordinate_lookup[start]
    end = self.__coordinate_lookup[end]
    dX = start[0] - end[0]
    dY = -(start[1] - end[1])
    print m.degrees(m.atan(dX/dY)) + 360 
    pygame.draw.line(screen,colour,start,end,2)

我尝试过使用角度和线条的渐变,Y坐标向下而不是向上增加的事实让我失望,我真的很感激在正确的方向上轻推。

3 个答案:

答案 0 :(得分:3)

这应该有效:

def draw_arrow(screen, colour, start, end):
    pygame.draw.line(screen,colour,start,end,2)
    rotation = math.degrees(math.atan2(start[1]-end[1], end[0]-start[0]))+90
    pygame.draw.polygon(screen, (255, 0, 0), ((end[0]+20*math.sin(math.radians(rotation)), end[1]+20*math.cos(math.radians(rotation))), (end[0]+20*math.sin(math.radians(rotation-120)), end[1]+20*math.cos(math.radians(rotation-120))), (end[0]+20*math.sin(math.radians(rotation+120)), end[1]+20*math.cos(math.radians(rotation+120)))))

对于组织不良的代码感到抱歉。但正如你所说,从左上角开始的坐标需要翻转一些数学运算。此外,如果您想将三角形​​从等边距更改为其他内容,则只需更改第4行中的rotation +/- 120,或更改不同半径的20*

希望这会有所帮助:)

答案 1 :(得分:2)

我将起点和终点坐标表示为startX, startY, endX, endY enter image description here

dX = endX - startX
dY = endY - startY

//vector length 
Len = Sqrt(dX* dX + dY * dY)  //use Hypot if available

//normalized direction vector components
udX = dX / Len
udY = dY / Len

//perpendicular vector
perpX = -udY
perpY = udX

//points forming arrowhead
//with length L and half-width H
arrowend  = (end) 

leftX = endX - L * udX + H * perpX
leftY = endY - L * udY + H * perpY

rightX = endX - L * udX - H * perpX
rightY = endY - L * udY - H * perpY

答案 2 :(得分:0)

弗拉基米尔的答案很好!对于将来访问的任何人,以下是可控制箭头各个方面的功能:

def arrow(screen, lcolor, tricolor, start, end, trirad):
    pg.draw.line(screen,lcolor,start,end,2)
    rotation = math.degrees(math.atan2(start[1]-end[1], end[0]-start[0]))+90
    pg.draw.polygon(screen, tricolor, ((end[0]+trirad*math.sin(math.radians(rotation)), end[1]+trirad*math.cos(math.radians(rotation))), (end[0]+trirad*math.sin(math.radians(rotation-120)), end[1]+trirad*math.cos(math.radians(rotation-120))), (end[0]+trirad*math.sin(math.radians(rotation+120)), end[1]+trirad*math.cos(math.radians(rotation+120)))))'