오늘은 우리와 상호작용하는 그림자를 표현하는 프로그램을 만들어 보겠습니다~~^^*
아래 동영상을 클릭하시면 오늘 공부 내용을 바로 시작(9:40)하실 수 있어요~~^^* 우와! 벡터 Dot Product를 오늘 끝내게 되는군요!! YEAH~!!!
우리가 벡터 A를 다양하게 조정하면, 벡터 B위에 드리우는 Scalar Projectiond의 값이 다양하게 바뀔 것 같아요~
이 Scalar Projection 값에 유닛벡터 B를 곱하면, 차양막 벡터 A가 바닥 벡터 B 위에 드리우는 그림자를 시각적으로 표현할 수 있게 될 것 같네~^^*
차양막의 방향과 길이가 바뀌면 그림자의 길이와 위치도 바뀌게 될 것 같아요~
벡터 B는 바닥이니까 고정해 두고요~~
차양막 벡터 A의 길이와 방향을 우리가 마우스로 조정해 볼까요~~^^* 우와!! 뭔가 원격 작동 차양막이 탄생되는 것인가요~~^^*?
길이와 각도가 조절되는 차양막이 바닥에 드리우는 그림자의 길이도 그에 따라 변하게 되겠네요~~!!!
let anchorPoint = createVector(100, 200);
//(100, 200)에 차양막을 붙잡아주는 앵커포인트를 튼튼하게 설치해 봅시다~
let tarpEndPoint = createVector(mouseX, mouseY);
//mouse로 차양막 끝자락 위치를 조정해 봅시다~
//원격조정 차양막 멋진데요!!
let tarp = p5.Vector.sub(tarpEndPoint, anchorPoint);
//차양막 끝자락 위치에서 앵커포인트 위치를 빼서, 실제 차양막 길이와 각도를 표현해 봅시다~
//벡터 tarpEndPoint에서 벡터 anchorPoint를 뺄셈하여 만든 벡터를 변수 tarp에 저장합니다~
let shade = vectorProjection(tarp, ground);
//벡터 tarp가 벡터 ground에 드리우는 Scalar Projection를 구합니다~
//벡터 ground의 유닛벡터와 Scalar Projection을 곱합니다~
//Scalar Projection의 크기를 가지고 벡터 ground의 방향성을 가진 벡터가 만들어 집니다~
//이 벡터를 변수 shade에 저장합니다~
그리고 저는, 벡터 덧셈을 이용하여, 그림자 끝자락과 바닥 끝을 표현하는 벡터도 따로 준비해 보았습니다.
선과 점을 표현할 때 위치 계산을 한 번 더 할 필요가 없을 것 같아요~
let shadeEndPoint = p5.Vector.add(shade, anchorPoint);
let groundEndPoint = p5.Vector.add(ground, anchorPoint);
//그림자 끝지점과 바닥 끝지점의 위치계산을 미리 해놓으면 어떨까요~
//선과 점을 표현할 때 위치계산을 따로 할 필요가 없겠지요~
//벡터 shade에 벡터 anchorPoint를 더하여 만든 벡터를 변수 shadeEndPoint에 저장합니다~
//벡터 ground에 벡터 anchorPoint를 더하여 만든 벡터를 변수 groundEndPoint에 저장합니다~
자 그럼, 이제 저와 함께 전체 코드를 살펴 볼까요~~^^*
function setup() {
createCanvas(400, 400);
ground = createVector(200, 60);
//x축 200 y축 60 만큼 이동하는 크기와 방향을 가진 벡터 ground입니다~
}
function vectorProjection(a, b) {
let bCopy = b.copy().normalize();
let sp = a.dot(bCopy);
bCopy.mult(sp);
return bCopy;
//벡터 b를 복사합니다~
//벡터 b의 복사본의 크기를 1로 만듭니다~
//벡터 b의 방향성을 가진 크기 1의 유닛벡터가 된 것을 변수 bCopy에 저장합니다~
//벡터 a와 벡터 b의 유닛벡터인 벡터 bCopy를 Dot Product하여 Scalar Projection을 구합니다~
//Scalar Projection을 변수 sp에 저장합니다~
//벡터 b의 유닛벡터인 벡터 bCopy를 Scalar Projection을 곱합니다~
//벡터 b의 방향성을 가지고 크기가 Scalar Projection이 된 벡터 bCopy를 return 합니다~
//bCopy는 이제 벡터 b에 드리워진 벡터 a의 Scalar Projection을 컴퓨터 화면에 시각적으로 표현하는 역할을 하게 될 것입니다~
}
function draw() {
background(0);
let anchorPoint = createVector(100, 200);
//(100, 200)에 차양막을 붙잡아주는 앵커포인트를 튼튼하게 설치해 봅시다~
let tarpEndPoint = createVector(mouseX, mouseY);
//mouse로 차양막 끝락자락 위치를 조정해 봅시다~
//원격조정 차양막 멋진데요!!
let tarp = p5.Vector.sub(tarpEndPoint, anchorPoint);
//차양막 끝자락 위치에서 앵커포인트 위치를 빼서, 실제 차양막 길이와 각도를 표현해 봅시다~
//벡터 tarpEndPoint에서 벡터 anchorPoint를 뺄셈하여 만든 벡터를 변수 tarp에 저장합니다~
let shade = vectorProjection(tarp, ground);
//벡터 tarp가 벡터 ground에 드리우는 Scalar Projection을 구합니다~
//벡터 ground의 유닛벡터와 Scalar Projection을 곱합니다~
//Scalar Projection의 크기를 가지고 벡터 ground의 방향성을 가진 벡터가 만들어 집니다~
//이 벡터를 변수 shade에 저장합니다~
let shadeEndPoint = p5.Vector.add(shade,anchorPoint);
let groundEndPoint = p5.Vector.add(ground, anchorPoint);
//그림자 끝지점과 바닥 끝지점의 위치계산을 미리 해놓으면 어떨까요~
//선과 점을 표현할 때 위치계산을 따로 할 필요가 없겠지요~
//벡터 shade에 벡터 anchorPoint를 더하여 만든 벡터를 변수 shadeEndPoint에 저장합니다~
//벡터 ground에 벡터 anchorPoint를 더하여 만든 벡터를 변수 groundEndPoint에 저장합니다~
strokeWeight(8);
stroke(255);
line(anchorPoint.x,anchorPoint.y,tarpEndPoint.x,tarpEndPoint.y);
line(anchorPoint.x,anchorPoint.y, groundEndPoint.x, groundEndPoint.y);
//고정점과 차양막끝자락을 연결하여 차양막을 시각화 해봅시다~
//고정점과 바닥끝을 연결하여 바닥을 시각화 해봅시다~
//anchorPoint 위치좌표와 tarpEndPoint의 위치좌표를 연결하는 선을 표현합니다~
//anchorPoint 위치좌표와 groundEndPoint의 위치좌표를 연결하는 선을 표현합니다~
strokeWeight(8);
stroke(0, 0, 255);
line(anchorPoint.x,anchorPoint.y,shadeEndPoint.x, shadeEndPoint.y);
//고정점과 그림자끝을 연결하여 그림자를 시각화 해봅시다~
//anchorPoint 위치좌표와 shadeEndPoint 위치좌표를 연결하는 선을 표현합니다~
strokeWeight(1);
stroke(255);
line(tarpEndPoint.x, tarpEndPoint.y,shadeEndPoint.x, shadeEndPoint.y );
//차양막끝자락과 그림자 끝자락을 얇은 흰 선으로 연결해 봅시다~
//(벡터 tarp가 벡터 ground 위로 드리우는 Scalar Project를 시각적으로 표현하는 벡터 shade의 끝부분인) 벡터 shadeEndPoint의 위치좌표를 벡터 tarpEndPoint의 위치좌표 연결합니다~
//벡터 tarp가 벡터 ground 위로 수직으로 내려오는 선(normal line)을 표현하는 선이기도 합니다~
//벡터 tarp의 끝자락 벡터 tarpEndPoint의 위치좌표와 벡터 ground사이의 거리를 표현하기도 합니다~
//normal line은 한 점과 한 선 사이의 거리를 계산할 때 중요해지는 개념이기도 합니다~
fill(0, 255, 255);
noStroke();
circle(anchorPoint.x, anchorPoint.y, 16);
//벡터 anchorPoint의 위치좌표를 하늘 색 동그라미로 표현합니다~
//차양막을 고정해 주는 지점입니다~
fill(0, 255, 0);
noStroke();
circle(tarpEndPoint.x, tarpEndPoint.y, 16);
//벡터 tarpEndPoint의 위치좌표를 녹색 동그라미로 표현합니다~
//차양막 끝자락 위치점입니다~
fill(255, 0, 0);
noStroke();
circle(shadeEndPoint.x, shadeEndPoint.y, 16);
//벡터 shadeEndPoint의 위치좌표를 빨강색 동그라미로 표현합니다~
//그림자 끝자락 위치점입니다~
}
자 그럼 이제 차양막을 마우스로 원격조정 해볼까요~~^^*
원격조정 기술을 우리가 실현해 내었네요!!! 와우!!!
아침 일찍 코딩공부를 마치고, 본격 일과를 시작하니까요~~ 휴일 저녁이 쉼의 시간이 되는 것 같아요~~^^*
어제 저녁에 여유있게 산책을 하고 맛있는 것도 사먹고 토요일 Down 휴일을 누렸는데요~~
음~~ 벡터 태양과 벡터 지표면 사이의 각도가 작아질 때~~ 하늘에는 노을이 생기잖아요~~~
어제 본 노을 선물 드려요~~ 맛있고 든든한 단백질 무기질 탄수화물 골고루 든 샐러드도 선물 드려요~ 아름다운 눈동자로 맛있게 보시고 맛있게 드셔요~~!!!



어머~~참 맛있는데 배도 부르시다구요~^^* 네~~ 샐러드 재료가 속을 든든하게 채워주는 재료들이라~~^^*
아 네!! 그럼 이제 우리 가까운 숲으로 캠핑을 가서 차양막을 설치하고 그늘에 앉아 숲 속 소리들에 귀기울여 볼까요~? 출발~~~^^*
원격조정 차양막 설치 도전을 오늘 저와 함께 해주셔서 감사합니다~~!!!
우리 내일은 이 차양막 아래에서 음악 함께 들어요~~^^*
그리고~~ 넵, 화요일부터 새로운 도전을 향해 뚜벅뚜벅 같이 걸어갈까요~~^^*
네!! 꿈은 이루어 집니다~~!!!
댓글 남기기