Silverback9

#야생으로

Creative Coding 독학 제144일 2024년08월18일(일)

오늘은 우리와 상호작용하는 그림자를 표현하는 프로그램을 만들어 보겠습니다~~^^*

아래 동영상을 클릭하시면 오늘 공부 내용을 바로 시작(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 휴일을 누렸는데요~~

음~~ 벡터 태양과 벡터 지표면 사이의 각도가 작아질 때~~ 하늘에는 노을이 생기잖아요~~~

어제 본 노을 선물 드려요~~ 맛있고 든든한 단백질 무기질 탄수화물 골고루 든 샐러드도 선물 드려요~ 아름다운 눈동자로 맛있게 보시고 맛있게 드셔요~~!!!

어머~~참 맛있는데 배도 부르시다구요~^^* 네~~ 샐러드 재료가 속을 든든하게 채워주는 재료들이라~~^^*

아 네!! 그럼 이제 우리 가까운 숲으로 캠핑을 가서 차양막을 설치하고 그늘에 앉아 숲 속 소리들에 귀기울여 볼까요~? 출발~~~^^*

원격조정 차양막 설치 도전을 오늘 저와 함께 해주셔서 감사합니다~~!!!

우리 내일은 이 차양막 아래에서 음악 함께 들어요~~^^*

그리고~~ 넵, 화요일부터 새로운 도전을 향해 뚜벅뚜벅 같이 걸어갈까요~~^^*

네!! 꿈은 이루어 집니다~~!!!

댓글 남기기