6.4 선 그리기 알고리즘
2023. 6. 6. 15:14ㆍ개인공부/게임수학
브레젠험 알고리즘을 구현하는 함수
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
void WindowsRSI::DrawLine(const Vector2& InStartPos, const Vector2& InEndPos, const LinearColor& InColor)
{
Vector2 clippedStart = InStartPos;
Vector2 clippedEnd = InEndPos;
Vector2 screenExtend = Vector2(_ScreenSize.X, _ScreenSize.Y) * 0.5f;
Vector2 minScreen = -screenExtend;
Vector2 maxScreen = screenExtend;
// 코헨 서덜랜드 직선 클리핑 알고리즘을 구현한 함수
// 시작지점과 마지막지점을 그리기 영역에 맞게 조절하는 함수
if (!CohenSutherlandLineClip(clippedStart, clippedEnd, minScreen, maxScreen))
{
// 그리기 밖영역인 경우
return;
}
// Vector2 -> ScreenPoint 구조체로 형변환
ScreenPoint startPosition = ScreenPoint::ToScreenCoordinate(_ScreenSize, clippedStart);
ScreenPoint endPosition = ScreenPoint::ToScreenCoordinate(_ScreenSize, clippedEnd);
// w,h
int width = endPosition.X - startPosition.X;
int height = endPosition.Y - startPosition.Y;
bool isGradualSlope = (Math::Abs(width) >= Math::Abs(height));
int dx = (width >= 0) ? 1 : -1;
int dy = (height >= 0) ? 1 : -1;
// 판별식에 사용하는 변수
int fw = dx * width;
int fh = dy * height;
// 최초 사용할 판별식 f를 저장한다.
int f = isGradualSlope ? fh * 2 - fw : 2 * fw - fh;
// 선이 변화없이 진행되는 경우에 사용할 판별식 조정값을 isGradualSlop에 따라서 구함
int f1 = isGradualSlope ? 2 * fh : 2 * fw;
int f2 = isGradualSlope ? 2 * (fh - fw) : 2 * (fw - fh);
// 최초의 선 그리기를 시작할 지점을 변수 x와 y에 각각 보관한다.
int x = startPosition.X;
int y = startPosition.Y;
// isGradualSlope 값에 따라 로직을 분기한다. 해당 값이 참이면 1,4,5,8 팔분면의 선 그리기가 진행된다.
if (isGradualSlope)
{
// 끝점에 도달할 때까지 로직을 계속 반복한다.
while (x != endPosition.X)
{
// 지정된 색상으로 스크린 좌표에 점을 찍는다.
SetPixel(ScreenPoint(x, y), InColor);
// 판벽식이 0보다 작으면 f1값을 사용해 판별식을 갱신한다.
if (f < 0)
{
f += f1;
}
// 판별식이 0보다 크거나 같으면 f2값을 사용해 판별식을 갱신한다.
else
{
f += f2;
y += dy;
}
// 다음 픽셀로 이동한다.
x += dx;
}
}
// isGradualSlope 값이 거짓이면 2,3,6,7 팔분면의 선 그리기를 진행한다.
else
{
while (y != endPosition.Y)
{
SetPixel(ScreenPoint(x, y), InColor);
if (f < 0)
{
f += f1;
}
else
{
f += f2;
x += dx;
}
y += dy;
}
}
}
|
cs |
'개인공부 > 게임수학' 카테고리의 다른 글
7-3 내적을 활용한 벡터의 투영 (0) | 2023.06.07 |
---|---|
7-1 내적을 활용한 목표물 감지 (0) | 2023.06.07 |
6-1 행렬 곱셈으로 이동 구현하기 (0) | 2023.06.05 |
5-2 역행렬을 사용해 원래 형태로 되돌리기 (0) | 2023.06.03 |