책/유니티로 배우는 게임 수학

[유니티로 배우는 게임 수학] 1장-삼각함수 복습 및 정리

바토파 2024. 8. 6. 18:03
반응형

- 1.1

삼각형은 세 개의 정점(꼭짓점, vertex)으로 이루어진다. 정점으로 세 개의 변(edge)이 정해진다.

삼각형은 항상 어딘가의 평면 위에 존재한다.

정점이 네 개인 도형은 더 이상 평면상에 없고, 3차원 공간에밖에 표현할 수 없다.

 

- 1.4

아크사인, 아크코사인, 아크탄젠트를 사용하면 각각 사인, 코사인, 탄젠트 값으로부터 대응하는 각도 θ를 산출할 수 있다.

 

- 1.5.4

90도 = π/2180도 = π 반지름이 1일 때 원주의 길이가 2π이기 때문에 이렇게 구해진다.라디안과 각도를 혼동하지 않도록 주의.

 

-1.5.5덧셈정리를 활용하여 임의의 점 (x, y)에 대한 원점 중심의 회전 알고리즘으로 사용할 수 있다.

 

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class Chapter01 : MonoBehaviour {

    private GameObject capsule;

    private float targetAngle = 0f;
    public float capsuleRotationSpeed = 4f;

    private GameObject sphere;
    private float buttonDownTime;

    public float sphereMagnitudeX = 2.0f;
    public float sphereMagnitudeY = 3.0f;
    public float sphereFrequency = 1.0f;
    
    void Start () {
       capsule = GameObject.Find("Capsule");
    }
    
    void Update () {
       // 마우스 좌클릭일 때 && 마우스 포인터가 특정 EventSystem 관련 UI용 GameObject 위에 없을 때
       if (Input.GetMouseButtonDown(0) && !EventSystem.current.IsPointerOverGameObject()) {
          Debug.Log (string.Format("mousePosition ({0:f}, {1:f})", Input.mousePosition.x, Input.mousePosition.y));

          targetAngle = GetRotationAngleByTargetPosition(Input.mousePosition);

          if (sphere != null) {
             Destroy(sphere);
             sphere = null;
          }

          sphere = SpawnSphereAt(Input.mousePosition);
          buttonDownTime = Time.time;
       }

       // 캡슐을 z축을 기준으로 회전
       capsule.transform.eulerAngles
          = new Vector3(0, 0, Mathf.LerpAngle(capsule.transform.eulerAngles.z, targetAngle, Time.deltaTime * capsuleRotationSpeed));
       // 현재 캡슐의 각도, 목표 각도, 메서드 1회 실행 시 진행되는 값 * 회전 속도

       if (sphere != null) {
          sphere.transform.position = new Vector3(
             sphere.transform.position.x + (capsule.transform.position.x - sphere.transform.position.x) * Time.deltaTime * sphereMagnitudeX,
             Mathf.Abs(Mathf.Sin ((Time.time - buttonDownTime) * (Mathf.PI * 2) * sphereFrequency) * sphereMagnitudeY),
              0
          );
       }
    }

    float GetRotationAngleByTargetPosition(Vector3 mousePosition) {
       Vector3 selfScreenPoint = Camera.main.WorldToScreenPoint(capsule.transform.position); // 캡슐의 월드 좌표를 스크린 좌표로 변환
       Vector3 diff = mousePosition - selfScreenPoint;
       
       float angle = Mathf.Atan2(diff.y, diff.x) * Mathf.Rad2Deg; // Mathf.Rad2Deg 라디안에서 도수로 변환

       Debug.Log (string.Format("angle: {0:f}", angle));

       float finalAngle = angle - 90f;

       Debug.Log (string.Format("finalAngle: {0:f}", finalAngle));

       return finalAngle;
    }

    GameObject SpawnSphereAt(Vector3 mousePosition) {
       GameObject sp = GameObject.CreatePrimitive(PrimitiveType.Sphere);
       Vector3 selfScreenPoint = Camera.main.WorldToScreenPoint(capsule.transform.position);
       Vector3 position = Camera.main.ScreenToWorldPoint(new Vector3(mousePosition.x, mousePosition.y, selfScreenPoint.z));
       sp.transform.position = new Vector3(position.x, position.y, 0);
       return sp;
    }
}

 

반응형