2014-04-06 4 views
0

컴퓨터를 사용하여 일부 hypotrochoids을 플롯하려고했지만 몇 가지 문제가 있습니다. 모르는 것과 들어 hypotrochoid의 파라미터 방정식은 :파이썬을 사용하여 hypotrochoids 플로팅

x(theta) = (R - r)cos(theta) + d*cos((R-r)/r*theta) 

y(theta) = (R - r)sin(theta) - d*sin((R-r)/r*theta) 

가 hypotrochoid의 위키에 대한 정의는 또한 설명 할 수있다 :

hypotrochoid가있다 반지름이 인 반경 r의 고정 된 원을 중심으로 회전하는 점에 의해 추적 된 룰렛 여기서 점은 내부의 중심은 입니다.

enter image description here

을하지만 그건 내 계산 방법을 사용하여 결말을하고 무엇을 확실히되지 않습니다 :

그래서 값 r = d = 1R = 3 가진 hypotrochoid는 다음과 같이 보일 것이다. (동일한 값) 내 hypotrochoid는 다음과 같이 보이는 다음 X 때문에

enter image description here

및 Y 값은 I 상정 각도 theta에서 x 및 y의 함수에 의해 결정된다 I 수 단순히 값을 반복 theta 0에서 2pi까지 그리고 특정 간격으로 x와 y 값을 개별적으로 계산 한 다음 좌표를 극좌표로 그립니다 (여기서 r**2 = x**2 + y**2). 그러나 나는 잘못 생각한 것 같습니다. 어쩌면 제 수식이 틀렸을 지 모르지만 방금 math stackexchange에있는 몇 명의 사람들과 확인해 보았습니다. 무엇이 잘못되었는지를 알 수 없었습니다. 내 방법이 잘못되면 hypotrochoid를 계산하기 위해 어떤 방법을 사용해야합니까?

class _BaseCurve(event.EventAware): 

    # This is a basic curve class from which all other curves inherit from (as 
    # you will see below with the Hypotrochoid class). Basically what happens is 
    # each new curve class must implement a function (relation) to calculate the 
    # radius of the equation at each angle interval, then plots the equation in 
    # other code elsewhere. 

    def __init__(self, radius, init_angle, end_angle, speed, acceleration, *args, **kwargs): 

     # Initialize geometric data... 
     self.radius = radius 

     # Initialize curve start and end angles... 
     self.init_angle = init_angle 
     self.end_angle = end_angle 

     # Initialize time-based curve attributes... 
     self.speed = speed 
     self.accel = acceleration 
     self.current_pos = 0 

     # Initialize defaults... 
     self.max_speed = inf 
     self.min_speed = neginf 

     self.args = args 
     self.kwargs = kwargs 

    def set_max_speed(self, speed): 
     """Set the maximum speed the path can achieve.""" 
     if speed < self.min_speed: 
      errmsg = "Max speed cannot be less than min speed." 
      raise ValueError(errmsg) 
     self.max_speed = speed 

    def set_min_speed(self, speed): 
     """Set the minimum speed the path can achieve.""" 
     if speed > self.max_speed: 
      errmsg = "Min speed cannot be greater than max speed." 
      raise ValueError(errmsg) 
     self.max_speed = speed 

    def set_acceleration(self, acceleration): 
     """Set a new acceleration for the path.""" 
     self.accel = acceleration 

    def move(self): 
     """Progress the path forward one step. 

     The amount progressed each time (curve).move is called 
     depends on the path's speed parameter and the distance 
     (i.e. angle_difference) it has to travel. The calculation 
     is as follows: 

     angle = angle_difference * current_position + init_angle 

     Where current_position is the position incremented by the 
     set speed in (curve).move(). 
     """ 
     self.current_pos += self.speed 
     if self.accel != 1: 
      new_speed = self.speed * self.accel 
      self.speed = max(min(new_speed, self.max_speed), self.min_speed) 

    def angle(self): 
     """Return the angle of the curve at the current position.""" 
     return self.angle_difference * self.current_pos + self.init_angle 

    def relation(self): 
     """Return the relationship of the current angle to the radius. 

     This is a blank function left to be filled in by subclasses of 
     _BasicCurve. The return value for this function must be a function 
     (or lambda expression), of which that function's return value should 
     be the radius of the curve at the current position. The parameters of 
     the return equation should be as follows: 

     (Assuming `r` is the function representing the relation): 

     radius = r(current_angle, *args, **kwargs) 

     Where *args and **kwargs are the additional *args and **kwargs specified 
     upon initializing the curve. 
     """ 
     return NotImplemented 

    def position(self): 
     """Calculate the position on the curve at the current angle. 

     The return value of this function is the coordinate in polar 
     form. To view the coordinate in cartesian form, use the 
     `to_cartesian` function. # Ignore the `to_cartesian` function in this code snippet, it simply converts polar to cartesian coordinates. 

     NOTE: This function requires self.relation to be implemented. 
     """ 
     r = self.relation() 
     theta = self.current_angle 

     args = self.args 
     kwargs = self.kwargs 

     radius = self.radius*r(theta, *args, **kwargs) 
     return radius, theta 

    @property 
    def angle_difference(self): 
     """The difference between the start and end angles specified.""" 
     return (self.end_angle - self.init_angle) 

    @property 
    def current_angle(self): 
     """The current angle (specified by self.current_pos).""" 
     return self.angle_difference * self.current_pos + self.init_angle 

Curve = _BaseCurve 

class Hypotrochoid(Curve): 
    def relation(self): 
     def _relation(theta, r, R, d): 
      x = (R - r)*math.cos(theta) + d*math.cos((R - r)/r * theta) 
      y = (R - r)*math.sin(theta) - d*math.sin((R - r)/r * theta) 
      return (x**2 + y**2)**(1/2) 
     return _relation 

답변

1

그것은 출력 극성 형태로 X, Y 및 세타를 변환하는 실수이다 : 여기

코드이다. Theta는 파라 메트릭 방정식의 매개 변수입니다. 곡선 점의 극점 각도가 아닙니다 (실제로는 작은 원 중심의 극각입니다).

그래서 x와 y는 바로 사용할 수있는 데카르트 좌표입니다. 이 지점을 영원한 발걸음을 내딛으십시오. 이것은 내가 변환 할 때

R := 120; 
    rr := 40; 
    d:= 40; 
    for i := 0 to 999 do begin 
    a := i * 2 * Pi/1000; 
    y := 200 + Round((R - rr) * sin(a) - d*sin((R-rr)/rr*a)); 
    x := 200 + Round((R - rr) * cos(a) + d*cos((R-rr)/rr*a)); 
    Canvas.Pixels[x, y] := clRed; 
    end; 
+0

계산식, 무슨 일이 일어나고 (Canvas.Pixels [X, Y]를 (x, y)가 좌표 점을 그립니다) 원하는 정확히 무엇을 그립니다 델파이 시험이다 (X ** 2 + y ** 2) ** (1/2)와 theta는 극형으로 변환 한 다음 데카르트 형태로 되돌아 간다. 무엇이 그것을 구체적으로 망쳐 놓는 원인입니까? – user3002473

+1

theta는 (x, y) 점의 극점이 아닙니다. 이 점에 대한 진정한 극점 각도는 atan2 (y, x)입니다. – MBo

+0

오하이오는 그렇게 많은 의미가 있습니다! 고맙습니다! – user3002473

관련 문제