https://youtu.be/DEqXNfs_HhY
이걸 보고 영감을 받아서
파이썬에서도 저런 걸 만들수 있지 않을까 해서 시도해봤음
먼저 광량 측정은 평면을 빛에 수직인 평면에 대해 정사영한거니까 광원으로부터 원위 점까지 벡터의 내적으로 각을 구하면 측정가능(아마)
프로그램 내의 상황임. 구하고 관찰자가 z축위에 있고 모니터는 xy평면인 상황임
5/15배라는건 잘못적은거
보이는 부분만 모니터에 표시해야하니까 시선벡터와 구의 벡터 내적이 0보다 클때만 보면 됨
그후 구 위의 점 좌표를 x,y,z라 하고
직각삼각형의 닮음에 따라 눈으로부터 xy평면의 거리인 5,
그리고 구 위의 점의 z좌표를 z라 했을 때 x y 좌표는 각각 5/(z+5)배가 됨
그래서 하루종일 만든 프로그램임
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
from math import *
# range함수는 float를 사용못해서 generator를 새로 만듦
def generator(start, end, step):
result = start
while result <= end:
yield result
result += step
coordinates = []
r = 5
# 구 위의 점 설정. x^2+y^2+z^2 = r^2 사용을 어떻게 하나 고민하고 있었는데 인터넷에서 답을 얻음
for azimuth in generator(0, 2*pi, 0.05):
for theta in generator(-pi/2, pi/2, 0.05):
x = r*cos(theta)*sin(azimuth)
y = r*sin(theta)
z = r*cos(theta)*cos(azimuth)
coordinates.append([x,y,z])
#만들어진 구는 0,0,0에 위치해 있기때문에 좌표들을 z축으로 10만큼 이동해줌
sphere_center = [0,0,10]
for coord in coordinates:
coord[2] += sphere_center[2]
lcx = int(input('Input light coordinate x:'))
lcy = int(input('Input light coordinate y:'))
lcz = int(input('Input light coordinate z:'))
light_coord = [lcx,lcy,lcz]
sight_coord = [0,0,-5]
sphere_vector = []
light_vector = []
sight_vector = []
#각 점마다 벡터 계산
for coord in coordinates:
sphere_vector.append([coord[0]-sphere_center[0], coord[1]-sphere_center[1], coord[2]-sphere_center[2]])
light_vector.append([light_coord[0]-coord[0], light_coord[1]-coord[1], light_coord[2]-coord[2]])
sight_vector.append([sight_coord[0]-coord[0], sight_coord[1]-coord[1], sight_coord[2]-coord[2]])
cosine = []
#내적으로 코사인값 구하기
for i in range(len(sphere_vector)):
sv = sphere_vector[i]
lv = light_vector[i]
a_dot_b = sv[0]*lv[0] + sv[1]*lv[1] + sv[2]*lv[2]
abs_a = sqrt(sv[0]*sv[0]+sv[1]*sv[1]+sv[2]*sv[2])
abs_b = sqrt(lv[0]*lv[0]+lv[1]*lv[1]+lv[2]*lv[2])
angle = a_dot_b/(abs_a*abs_b)
cosine.append(angle)
#광량 계산 0-1사이의 값이 나오게 됨
luminance = []
for cos in cosine:
if cos >= 0:
sine = sqrt(1-cos*cos)
luminance.append(sine)
else:
luminance.append(0)
#모니터에 출력할 좌표 계산
output_coordinates = []
for i in range(len(sphere_vector)):
sv = sphere_vector[i]
siv = sight_vector[i]
a_dot_b = sv[0]*siv[0]+sv[1]*siv[1]+sv[2]*siv[2]
if a_dot_b >= 0:
scale = abs(sight_coord[2])/(coordinates[i][2]-sight_coord[2])
output_coordinates.append([scale*coordinates[i][0], scale*coordinates[i][1], 0, luminance[i]])
xplot = [[],[],[],[],[],[],[],[],[],[],[]]
yplot = [[],[],[],[],[],[],[],[],[],[],[]]
#광량 정도에 따라 좌표들을 나눠서 출력함
for l in output_coordinates:
lum = round(l[3],1) * 10
xplot[int(lum)].append(l[0])
yplot[int(lum)].append(l[1])
import matplotlib.pyplot as plt
for i in range(11):
plt.plot(xplot[i], yplot[i], 'o')
plt.show()
|
cs |
이거 좌표는 다 구했는데 어떻게 출력할지가 막막해서 시간 존나게 날려먹음
사실 생각하고 있었던건 저 스피닝 도넛처럼 캐릭터로 그리드 만들어서 좌표들을 그 그리드 안에 우겨넣어서 ascii글자로 출력하고 싶었는데
많은 시행착오를 거쳐도 도저히 할수가 없었음...
그래서 대안을 찾아보다가 matlab을 발견해서 활용하기로 함
matlabㅈㄴ 좋은거같음
다음은 결과 사진들임
위에껀 광점을 7,7,7로 잡은거고 아래사진은 10,10,-10로 잡은것
아름답다...