pygame,在半径R内从A点到B点画一条弧

2024-09-30 10:33:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我试着沿着半径R.A半圆,从A点到B点画一条弧。在

Player.__draw_fov()中,您可以看到我当前是如何绘制圆弧的。但是,当我旋转弧线超过90度时,它就会变得混乱。现在,当我做向量运算来得到fov向量与默认向量(x,0)的角度时,它总是返回一个值0 <= angle <= 180。所以它适用于最高的180度到0度。但对底部180到360度不起作用。在

现在我尝试了各种方法,包括跟踪球员的角度。从90开始(面朝上)(0面朝右)。当玩家面对低于0或高于180度时,它会改变角度。但似乎什么都不管用。在

class Player:

    def __init__(self, distance, fov, color, start, pygame, screen):
        self.distance = distance
        self.fov = fov
        self.color = color
        self.pygame = pygame
        self.screen = screen
        self.left = False
        self.right = False

        self.angularSpeed = 5
        self.speed = 5

        self.angle = 90
        self.origin = start

        unit = 1 / numpy.linalg.norm(numpy.array([0, -10]))

        self.points = numpy.array([
            numpy.array([-3, 3]) + start,
            numpy.array([3, 3]) + start,
            numpy.array([0, -10]) + start,
            self.rotate([0, distance * unit * -10], self.fov / 2) + start,
            self.rotate([0, distance * unit * -10], -self.fov / 2) + start
        ])

    def update(self):
        if self.left: self._left()
        elif self.right: self._right()
        self._draw_body()
        self._draw_fov()

    def _draw_fov(self):
        P1 = self.points[3]
        P2 = self.points[4]
        self.pygame.draw.line(self.screen, self.color, self.origin, P1.tolist())
        self.pygame.draw.line(self.screen, self.color, self.origin, P2.tolist())

        O = numpy.array([10, 0])
        A1 = self.vector_angle(P1-self.origin, O)
        A2 = self.vector_angle(P2-self.origin, O)

        if self.angle >= 135: A2 = -A2
        if self.angle >= 225: A1 = -A1
        if self.angle <=  45: A1 = -A1
        if self.angle >= 315: A2 = -A2

        O_corner = self.origin - numpy.array([self.distance, self.distance])

        if (135 <= self.angle < 225) or
           (0 <= self.angle <= 45) or
           (315 <= self.angle < 360):
            self.pygame.draw.arc(self.screen, self.color, (O_corner, (self.distance * 2, self.distance * 2)), math.radians(A1), math.radians(A2))
        else:
            self.pygame.draw.arc(self.screen, self.color, (O_corner, (self.distance * 2, self.distance * 2)), math.radians(A2 - 90), math.radians(A1 + 90))

    def vector_angle(self, A, B):
        dot = A[0] * B[0] + A[1] * B[1]
        norm = numpy.linalg.norm(A) * numpy.linalg.norm(B)

        return math.degrees(math.acos(dot/norm))

    def _left(self):
        self.angle = (self.angle + self.angularSpeed) % 360
        for point in range(self.points.shape[0]):
            self.points[point] = self.rotate(self.points[point], -self.angularSpeed, self.origin)
        self.directionVector = self.rotate(self.directionVector, -self.angularSpeed)

    def _right(self):
        self.angle = (self.angle - self.angularSpeed) % 360
        for point in range(self.points.shape[0]):
            self.points[point] = self.rotate(self.points[point], self.angularSpeed, self.origin)
        self.directionVector = self.rotate(self.directionVector, self.angularSpeed)

编辑 更改并格式化为更加惯用(三元比较和%模,它适用于负数)。不再需要进行lt>;和lt>;比较。在

编辑

我改进了算法,使它在转弯时画得更好,当你转弯时它似乎是正确的。 然而,随着时间的推移,随着球员不断转向,弧线开始错误地画出。这似乎是一个累积的问题,我看不到。累积问题在_right()内,它发生在360-自身角度,这是用360+修复的自身角度在

enter image description here

enter image description here

enter image description here


Tags: selfnumpya1originarrayscreenpygamestart
1条回答
网友
1楼 · 发布于 2024-09-30 10:33:39

通过保持一个角度变量来表示玩家所面对的方向,并使用这个变量来调整两个FOV向量和原点向量之间的向量角([10,0]),我就能够调整角度,这样它就总能正确地画出弧线。在

每个角度根据是否自身角度超过了45度。基本上,当FOV在圆的下半部分时,这就通知了。因为使用向量来获得角度只能在0到180度之间工作,所以它不考虑超过180度的角度,因为这些只是0到-180之间的负值,而向量并不关心这些值。在

这些角度只适用于90度的视野。为了补偿任何fov,我对它们进行了如下修改:

if self.angle >= 180-self.fov/2: A2 = -A2
if self.angle >= 180+self.fov/2: A1 = -A1
if self.angle <=  self.fov/2: A1 = -A1
if self.angle >= 360-self.fov/2: A2 = -A2

# if self.angle >= 135: A2 = -A2 # 90 + 45
# if self.angle >= 225: A1 = -A1 # 180 + 45
# if self.angle <=  45: A1 = -A1 # 45
# if self.angle >= 315: A2 = -A2 # 270 + 45

O_corner = self.origin - numpy.array([self.distance, self.distance])

if (self.angle >= 135 and self.angle < 225) or (self.angle <= 45 and self.angle >= 0) or (self.angle >= 315 and self.angle < 360):
self.pygame.draw.arc(self.screen, self.color, (O_corner, (self.distance*2, self.distance*2)), math.radians(A1), math.radians(A2))
else:
    self.pygame.draw.arc(self.screen, self.color, (O_corner, (self.distance*2, self.distance*2)), math.radians(A2-90), math.radians(A1+90))

我问题中的代码已经更新

相关问题 更多 >

    热门问题