티스토리 뷰
728x90
반응형
점과 선, 이번에는 곡선입니다.
곡선은 원뿔에서 나옵니다.
네. 곡선(쌍곡선, 원, 타원, 한쪽곡선)은 두개의 원뿔로 부터 구할 수 있습니다.
이러한 곡선의 Pixel화 역시 직선에 방정식에서 사용한 Bresenham알고리즘을 사용하면
화면에 Pixel화 하여 Display하는것이 가능합니다.
아래는 이제 곡선을 예로 들어보겠습니다.
곡선의 방정식 역시 X좌표를 이동하면서, next X에서 next Y와 Next Y+1의 사이점을 곡선값과 비교하게 됩니다.
이 비교식을 통해서 판별식을 만들고, 만들어진 판별식으로 각 X마다의 Next X에서 Y값을 구하게 됩니다.
원의 방정식을 예로 판별식을 봅시다.
이때, 직선과 다르게 곡선은 미분값이 일정하지 않습니다.
때문에 X의 위치마다 n의 값을 바꿔가며 판별을 해 줘야합니다.
(물론, 방법을 잘만 사용하면 미분값이 -1~0인 지점을 사용하면 위 방법이 필요 없습니다 :) )
Python으로 구현된 원의 Pixel화 소스코드입니다.
class circle:
def __init__(self, x, y, radius):
#원의 중심 + 반지름을 저장할 속성을 선언합니다.
self.c_x = x
self.c_y = y
self.r = radius
#1사분면의 0~45도를 기준으로 계산할 것이기 때문에
#1사분면의 x의 Max값을 구해줍니다.
self.this_x = self.c_x + self.r
self.this_y = self.c_y
#1사분면에서 원의 45도 위치의 x좌표를 저장합니다.
self.end_x = round(self.c_x + self.r*(1/pow(2, 1/2)),0)
self.route_point = []
#각 축점을 저장합니다.
self.route_point = self.route_point + [[self.c_x + self.r, self.c_y]]
self.route_point = self.route_point + [[self.c_x - self.r, self.c_y]]
self.route_point = self.route_point + [[self.c_x, self.c_y + self.r]]
self.route_point = self.route_point + [[self.c_x, self.c_y - self.r]]
#Bresenham의 알고리즘과 유사하게 다음 점의 위치를 찾는 판별식을 구성합니다.
def j_eq(self,x,y):
#이때, 원의 접선의 기울기는 -1~-무한대의 값을 갖습니다(1사분면 0~45도 사이)
#때문에 x-1에서 y의 값은 y,y+1만이 아니라, y+n, y+n+1사이 중 어떤값을 고르지 결정해야합니다.
n = 0
while True:
#기존 원의 값이 y+n과 y+n+1에 들어올때까지 n을 증가시켜줍니다.
j_const = pow(((x-1)-self.c_x),2)+pow((y+(n)-self.c_y),2)-pow(self.r,2)<=0
j_const_up = pow(((x-1)-self.c_x),2)+pow((y+(n+1)-self.c_y),2)-pow(self.r,2)>=0
#이제 y+n~y+n+1 사이에 원의 실제 값이 있다면 판별식으로 x-1에서 y의 값을 정합니다.
if j_const and j_const_up:
#이 경우 원의 반지름이 원점에서 [x-1, y+n+0.5]보다 긴 것이므로
#원의 값보다 y+n+0.5가 아래 있으므로, y값은 n+1만큼만 증가합니다.
if pow(((x-1)-self.c_x),2)+pow((y+(n+0.5)-self.c_y),2)-pow(self.r,2)<0:
return [x-1, y+n+1]
#이 경우 원의 반지름이 원점에서 [x-1, y+n+0.5]보다 짧은 것이므로
#원의 값보다 y+n+0.5가 위 있으므로, y값은 n만큼만 증가합니다.
elif pow(((x-1)-self.c_x),2)+pow((y+(n+0.5)-self.c_y),2)-pow(self.r,2)>0:
return [x-1, y+n]
n = n+1
def cal(self):
#1사분면의 0~45도 까지만 Point를 계산합니다.
while self.this_x >= self.end_x:
#현재의 x,y 값을 통해서 판별식을 진행하고, 판별식 결과를 다시 받습니다
#이 점들을 모아서 1사분면의 0~45도 사이의 Plot Point를 산출합니다.
self.this_x, self.this_y = self.j_eq(self.this_x, self.this_y)
self.route_point = self.route_point + [[self.this_x, self.this_y]]
#모든 점을 8배화 합니다.(0~45도 사이에서 구한 점을 이용해서, 다른 사분면을 채웁니다.)
#이때 원의중심이 0,0이 아니라면 해당 Point를 임시로 0,0으로 옮긴 후 계산,
#다시 원점의 위치를 이동시켜 주면 빠른게 모든 점의위치를 계산할 수 있습니다.
for i in range(len(self.route_point)):
ori_point = [self.route_point[i][0]-self.c_x, self.route_point[i][1]-self.c_y]
self.route_point = self.route_point + [[-ori_point[0]+self.c_x,ori_point[1]+self.c_y]]
self.route_point = self.route_point + [[ori_point[0]+self.c_x,-ori_point[1]+self.c_y]]
self.route_point = self.route_point + [[-ori_point[0]+self.c_x,-ori_point[1]+self.c_y]]
self.route_point = self.route_point + [[ori_point[1]+self.c_x,ori_point[0]+self.c_y]]
self.route_point = self.route_point + [[-ori_point[1]+self.c_x,ori_point[0]+self.c_y]]
self.route_point = self.route_point + [[ori_point[1]+self.c_x,-ori_point[0]+self.c_y]]
self.route_point = self.route_point + [[-ori_point[1]+self.c_x,-ori_point[0]+self.c_y]]
#plot에 사용될 x, y 반지름을 정해줍니다.
c_x, c_y, radius = [30, 10, 108]
#알고리즘으로 그려진 pixel과 비교할 실제 원(Float값)을 구해줍니다.
def c_eq(x):
return [[x,c_y + pow(pow(radius,2)-pow((x-c_x),2), 1/2)],[x,c_y - pow(pow(radius,2)-pow((x-c_x),2), 1/2)]]
real_circle = []
for i in range(c_x-radius-1, c_x+radius+1):
temp = c_eq(i)
real_circle = real_circle + [temp[0]]
real_circle = real_circle + [temp[1]]
#선택된 조건으로 Pixel화된 원을 산출합니다.
test = circle(c_x,c_y,radius)
test.cal()
#시각화하여 두 원을 비교합니다.
import matplotlib.pyplot as plt
plt.figure(figsize = [5,5])
plt.scatter([test.route_point[i][0] for i in range(len(test.route_point))], [test.route_point[i][1] for i in range(len(test.route_point))], s = 10)
plt.scatter([real_circle[i][0] for i in range(len(real_circle))],[real_circle[i][1] for i in range(len(real_circle))], s = 0.5)
728x90
반응형
'컴퓨터 그래픽스' 카테고리의 다른 글
6. 채색 알고리즘(수정중) (0) | 2021.02.15 |
---|---|
5. 기하변환 3(복합기하변환, 아핀변환) (0) | 2021.02.13 |
4. 기하변환2(동차좌표ver) (0) | 2021.02.12 |
3. 기하변환1(기본기하변환) (0) | 2021.02.11 |
1. 점과 선 (0) | 2021.02.09 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 자료구조
- 병렬처리
- GDC
- 이분탐색
- 프로그래머스
- 분할정복
- AVX
- 완전탐색 알고리즘
- git
- 동적계획법
- 알고리즘
- prime number
- Greedy알고리즘
- 코딩테스트
- 컴퓨터그래픽스
- C++
- stack
- hash
- Sort알고리즘
- Search알고리즘
- Python
- 사칙연산
- heap
- SIMD
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
글 보관함