【问题标题】:Drawing arrowheads which follow the direction of the line in PyGame在 PyGame 中绘制沿线方向的箭头
【发布时间】:2017-09-17 13:57:47
【问题描述】:

在 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 坐标向下而不是向上增加的事实让我感到厌烦,我真的很感激朝着正确的方向轻推。

【问题讨论】:

标签: python python-2.7 pygame geometry algebra


【解决方案1】:

这应该可行:

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 更改为不同的半径即可。

希望这会有所帮助:)

【讨论】:

    【解决方案2】:

    我将开始和结束坐标表示为startX, startY, endX, endY

    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
    

    【讨论】:

      【解决方案3】:

      弗拉基米尔的回答很棒!对于将来访问的任何人,这里是控制箭头各个方面的功能:

      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)))))'
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-04-09
        • 1970-01-01
        • 1970-01-01
        • 2022-01-13
        • 1970-01-01
        • 1970-01-01
        • 2020-03-07
        • 2011-09-28
        相关资源
        最近更新 更多