플러터에 대한 두 번째 포스팅입니다.
본 포스팅에서는 중심점에서 특정 각도의 좌표를 구하는 방법에 대해 다뤄보도록 하겠습니다.
이전 포스팅과 마찬가지로 좌표와 관련한 계산은 삼각비 계산이 필요합니다.
삼각비는 직각삼각형에서 특정 두 변의 비율을 의미합니다.
본 예시 이미지에서는 우측 변이 직각임을 기준으로 작성하였습니다.
본 포스팅에서는 평면인 상태에서의 X, Y 좌표를 구하는 것에 대해 알아보겠습니다.
본 포스팅에서 작성하게 될 코드의 결과는 아래와 같습니다.
본 포스팅에서 적용할 삼각비는 cos와 sin입니다.
cos는 밑변/빗변의 값으로 빗변에 대한 밑변의 비율을 구할 수 있습니다.
즉, 빗변이 늘어나면 늘어나는 밑변의 비율을, 빗변 줄어들면 줄어드는 밑변의 비율을 구할 수 있습니다.
좌표계의 X, Y 중 X의 값을 구할 수 있게 됩니다.
sin은 높이/빗변의 값으로 빗변의 증감에 의한 높이의 비율, Y의 값을 구할 수 있습니다.
1. 각도를 라디안으로 변환
대부분의 프로그래밍 언어는 60분법의 각도(degree) 단위보다는 호도법(radian)을 기준으로 하는 경우가 많습니다.
호도법은 특정 원의 반지름만큼 원의 호만큼의 길이의 각도를 1 라디안으로 나타내는 단위입니다.
1 라디안은 180/π = 57.296°입니다. 라디안은 원의 크기와 관계없이 일정합니다.
먼저 사람이 사용하기에 편한 단위는 각도이므로 이를 라디안 단위로 변환해줄 코드를 작성할 필요가 있습니다.
1°는 π/180 = 0.0174533입니다.
즉, π/180에 원하는 각도를 곱해주면 원하는 각도의 라디안 단위를 얻을 수 있습니다.
여기까지 알 수 있다면 코드 작성은 간단합니다.
//각도를 라디안으로 변환
double degreeToRadian({required double degree}) {
return degree * (pi / 180);
}
2. 중심점에서 특정 각도에 대한 삼각비
위 코드에서 구한 라디안을 이용해 X, Y 값의 비율을 구해야 합니다.
이 항목에서는 구현 흐름을 고려해서 코드를 표기합니다.
// x 좌표의 비율(빗변 길이에 대한 밑변 길이의 비율)
cos(degreeToRadian(degree: degree))
// y 좌표의 비율(빗변 길이에 대한 높이의 비율)
sin(degreeToRadian(degree: degree))
삼각함수에 해당하는 cos와 sin을 사용하기 위해서는 dart:math 패키지를 import 해야 합니다.
import 'dart:math';
비율은 구했지만 중심점에서 얼마만큼 떨어진 곳에 그릴 지를 정의하지 않았으므로 정확히 원하는 위치에 그리기 위한 변수가 추가로 필요합니다.
이를 고려해 다음과 같이 함수를 완성합니다.
// 기준점에서 특정 각도 + 거리(distance) 만큼 떨어진 곳의 좌표를 구함
Offset getPos({required double degree, required double distance}) {
double dx = distance * cos(degreeToRadian(degree: degree)) + 0; // 중심 객체의 x좌표
double dy = distance * sin(degreeToRadian(degree: degree)) + 0; // 중심 객체의 y좌표
return Offset(dx, dy);
}
기준 좌표는 0, 0으로 가정합니다. (이후 작성할 코드를 고려해 의미 없는 연산이지만 + 0을 포함해줍니다.
이제 다음과 같은 형태로 getPos 함수를 사용할 수 있습니다.
//중심으로부터 0.5 만큼 떨어진 거리
double distance = 0.5;
getPos(degree: 0, distance: distance);
지금까지 작성한 코드는 사전에 중심점의 좌표가 정의되어 있어야만 사용할 수 있습니다.
아래와 같이 코드를 수정 및 완성합니다.
3. 최종 코드 완성
위 코드는 플러터 프로젝트에 바로 붙여 넣어서 사용할 수 있습니다.
클래스가 호출되면 다음과 같은 순서로 화면을 빌드하게 됩니다.
1. rootOffset변수로 중심점 좌표 정의 (0, 0)
2. 그리고자 하는 위치의 범위(distance) 정의
3. initState 함수에서 중심각으로부터 상하좌우, 대각선 위치에 해당하는 곳의 좌표를 획득 (offsets)
4. 그리고자 하는 위젯에 좌표 적용
5. 화면 빌드
여기서 distance의 범위가 0 ~ 1.0인 이유는 위 예시에서는 위치 정의를 alignment로 하기 때문입니다.
Position위젯에 적용하려면 픽셀 값을 적용하면 됩니다.
본 예제에서는 alignment를 기반으로 작성했기 때문에 화면의 종횡비의 차이가 심할 경우 다음과 같이 찌그러져 보일 수 있습니다.
예쁜 원형 구도로 보려면 Stack & Positioned 위젯에 적용하거나 exe로 빌드해 화면을 충분히 크게 늘리면 확인할 수 있습니다.
'Dev > Flutter' 카테고리의 다른 글
[Flutter] CustomPainter를 이용한 팩맨 애니메이션 그리기 (0) | 2021.12.30 |
---|