2017-10-27 1 views
0

반지름 R을 따라 점 A에서 점 B까지 호를 그리려합니다. 반원입니다.파이 게임 반지름 R에서 점 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 (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)) 

    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.angularSpeed 
     if self.angle > 360: self.angle = self.angle - 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.angularSpeed 
     if self.angle < 0: self.angle = 360 + self.angle 
     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) 

편집 나는 당신이 설정으로 올바른 것 같다, 그것은 회전으로 더 나은 호를 그리는 알고리즘을 개선. 그러나 시간이 지남에 따라 아크는 플레이어가 계속 변함에 따라 잘못 그리기 시작합니다. 이것은 내가 볼 수없는 누적 된 문제인 것 같습니다. self.angle이가 유지하여 360 + self.angle

enter image description here

enter image description here

enter image description here

+0

은 아마 당신은 라디안 I/O도 시도해야 다음과 같이 어떤 FOV 보상하기 위해 내가 그들을 수정 –

답변

0

으로 고정 - 360 여기서 누적 문제 _right() 내부에서, 그것이 발생한 각도 변수를 사용하여 플레이어가 직면하고있는 방향을 나타내며 두 ​​개의 FOV 벡터와 원점 벡터 ([10, 0]) 사이에서 계산 된 벡터 각도를 적용하는 데 사용합니다. 각도를 적용하여 항상 호를 올바르게 그리도록했습니다.

각 각도는 self.angle이 특정 45도 지점을 벗어 났는지에 따라 FOV 벡터의 각도를 수정합니다. 기본적으로 이것은 FOV가 원의 아래쪽 절반에있을 때 알려줍니다. 벡터를 사용하여 각도를 얻는 것은 0에서 180도 사이에서만 작동하기 때문에 벡터가 신경 쓰지 않는 0과 -180 사이의 음수 값이므로 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)) 

내 문제의 코드가 업데이트되었습니다 및

관련 문제