(์์ญ) Separating Axis Theorem(SAT) ์ค๋ช
[์๋ฌธ]
https://www.sevenson.com.au/actionscript/sat/Separating Axis Theorem(SAT)๋ ๋ณผ๋ก๋ค๊ฐํ(convex polygons) ์ฌ์ด์ ์ถฉ๋์ ๊ณ์ฐํ๊ธฐ ์ํ ๊ธฐ๋ฒ์ ๋๋ค.
์ ๊ฒฐ์ฝ ์ ๋ฌธ๊ฐ๋ ์๋์ง๋ง, ์ ์๊ฒ Collision Detection์ด ํ์ํด์ง ๋ค์๋ถํฐ,
์ ๋ ๊ด๋ จ ์๋ฃ๋ค์ ๋ชจ์์๊ณ , ๊ฒฐ๊ตญ ์ด๋ฅผ ActionScript 3๋ก ๊ตฌํํ์ต๋๋ค.
๋ค๋ฅธ ์ด๋ค์ด (์ ์ ๊ฐ์ด) ๊ณ ํต์ ๊ฒช์ง ์์์ผ๋ฉด ํ๋ ๋ง์์, ์ด๋ฅผ ๊ณต์ ํฉ๋๋ค.
Flash์์ Polygon๋ค ์ฌ์ด์ ์ถฉ๋๊ณ์ฐ์ด ํ์ํจ์ ๋๊ผ์ ๋๋ถํฐ,
์ ๋ ์ผ๋ช '๋ถ๋ฆฌ์ถ ๊ฒ์ฌ ์ด๋ก (SAT)'๋ก ์๋ ค์ง ์ด ๋ฐฉ๋ฒ์ ์๊ฒ๋์์ต๋๋ค. ์ ์ผํ ๋ฌธ์ ๋, ์ ๊ฐ ์ด๋ฅผ ์ ๊ฒ์ผ๋ก ๋ง๋ค๊ธฐ์ํด ์์ฒญ๋๊ฒ ๊ณ ์ํ๋ค๋ ๊ฒ์ด์ง์.
์์ฃผ ๋ง์ Collision Detection ์๋ฃ๋ฅผ ์ฝ๊ณ , ์ฝ๋ ์ํ์ ์กฐ์ฌํ ๋ค์์ผ ํ์ ํ ์ ์์์ต๋๋ค.
์ํฌ์(?)๋ค์ ์ํด, ๋จผ์ ์ด ์ด๋ก ์ ๊ธฐ๋ณธ์ ์ธ ์๋ฆฌ๊ฐ ์ด๋ป๊ฒ ์๋ํ๋์ง๋ฅผ ๊ฐ๋ณ๊ฒ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
The quick rundown
์ผ๋ฐ์ ์ผ๋ก, SAT์ ๋ชฉ์ (๊ทธ๋ฆฌ๊ณ ๋ค๋ฅธ ๋ชจ๋ Collision Detection ๊ธฐ๋ฒ) ์ ๋ชฉํ๋
๋ Shape ์ฌ์ด์ ๊ฐ๊ฒฉ์ด ์กด์ฌํ๋ ์ง๋ฅผ ํ
์คํธ ํ๋ ๊ฒ์
๋๋ค.
์ ๊ฐ ์๋, SAT์ ๋ํ ๊ฐ์ฅ ์ข์ ๋น์ ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
[ ํ๋ถ์ ์ผ ๋ค์, ๋น์ ์ด ํ
์คํธ ํ๋ ค๋ ๋ Shape๋ฅผ ๋ค๋ฅธ ๊ฐ๋๋ก ๋น์ถ๋ค๊ณ ์์ํด ๋ณด์ธ์.
์ด๋ค ๊ทธ๋ฆผ์์ ํํ๊ฐ, ๊ทธ ๋ Shape ๋ฐ๋ก ๋ค์ ๋ฒฝ์ ๋ํ๋ ๊น์? ]
๋ฐ๋๋ก ๋ง์ฝ ๊ฐ๊ฒฉ์ ์ฐพ๋๋ค๋ฉด, ๋ถ๋ช ํ ์ ์ดํ์ง ์์ ์ํ์ผ ๊ฒ์ ๋๋ค.
Programming์ ๊ด์ ์์, ์ด๋ ์ด~์์ฒญ ๋ง์ ๋ชจ๋ ๊ฐ๋์์ ์ด๋ฅผ Checkํด์ผ ํจ์ ์๋ฏธ ํ ๊ฒ์ ๋๋ค.
๋คํ์ธ ๊ฒ์, Polygon์ ๋ฒ์น ๋๋ถ์ Check ํด์ผํ key ๊ฐ๋์ ์๋ ๋ช๊ฐ ๋์ง ์๋๋ค๋ ๊ฒ์ ๋๋ค.
๋น์ ์ด check ํด์ผ ํ ๊ฐ๋(Angle)์ ์๋ polygon์ ๋ณ์ ์์ ๊ฐ์ต๋๋ค.
์ด๋ check ํด์ผ ํ ์ต๋ angle์ ์๋, ๋ shape์ ๋ณ์ ์์ ํฉ๊ณผ ๊ฐ๋ค๋ ๊ฒ์ ๋๋ค.
(ex - ๋ 5๊ฐํ์ 10๊ฐ์ angle์ ์ฒดํฌํด์ผ ํฉ๋๋ค.)
(ํด๋น ํฌ์คํธ๋ 2D Collision์ผ๋ก ์ํฉ์ ํ์ ํ ๊ฒ ๊ฐ์)
So how do you make it work in code?
์์ฃผ ๊ฐ๋จํ์ง๋ง, ๋ฐ๋ณต์ ์ธ ๋ฐฉ๋ฒ์
๋๋ค. ์ฐจ๊ทผ์ฐจ๊ทผ ์ดํด๋ณด์ง์.
[ STEP 1 ]
ํ
์คํธ ํ๋ ค๋ polygon ์ค ํ๊ฐ์ ๋ณ์ ์ ํํ๊ณ , ๊ทธ ๋ณ์ normal vector๋ฅผ ์ฐพ์ผ์ธ์.์ด๊ฒ์ '์ถ(Axis)'์ด ๋ ๊ฒ์ ๋๋ค.
[ STEP 2 ]
์ฒซ๋ฒ์งธ polygon์ ๋ชจ๋ ๊ผญ์ง์ ์ ์ํํ๋ฉด์, (๊ฐ ๊ผญ์ง์ ์) ์ถ์ projection ํ์ธ์.
(๋์์, ์ด polygon์ ๋ํ ๊ทธ ๊ฐ๋ค ์ค ์ต๋๊ฐ๊ณผ ์ต์๊ฐ์ checkingํ์ธ์)
[ STEP 3 ]
๋๋ฒ์งธ polygon์ ๋ํด์๋ ๊ฐ์ ๋ฐฉ๋ฒ์ผ๋ก checkํ์ธ์.
[ STEP 4 ]
๊ทธ ํ, ๊ทธ value๋ค์ด overlap ๋๋์ง๋ฅผ check ํ์ธ์.๋ง์ฝ ์ถ์ ๋ํด projectionํ ๋ค์,
๋ Shadow ์ฌ์ด์์ gap์ ๋ฐ๊ฒฌํ๋ค๋ฉด, ๋ shape๋ ๋ถ๋ช ํ intersectํ์ง ์๋ ๊ฒ์ ๋๋ค.
๊ทธ๋ฌ๋ ๋ง์ฝ gap์ด ์กด์ฌํ์ง ์๋๋ค๋ฉด, ๋ shape๋ ์ ์ดํ ์๋ ์์ผ๋ฉฐ,
๋น์ ์ ๋ polygon์ ๋ชจ๋ ๋ณ์ ์ํํ๋ฉด์ checking์ ์ด์ด๊ฐ์ผ ํฉ๋๋ค.
๋ชจ๋ ๋ณ์ ๋ํด gap์ ๋ฐ๊ฒฌํ์ง ๋ชปํ๋ค๋ฉด, ์ด์ ๊ทธ ๋ shape๋ ์ถฉ๋ํ๋ ๊ฒ์ ๋๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก ์ด๋ ์ต๋๋ค.
์ถ๊ฐ๋ก ํ๋๋ฅผ ๋ง๋ถ์ด์๋ฉด,
overlapํ๋ shadow๋ค ์ค์์ ๊ฐ์ฅ ์๊ฒ overlapํ๋ ์ถ์ ์ฐพ๋๋ค๋ฉด,
๋น์ ์ ๊ทธ value๋ฅผ (์ถฉ๋ํ)๋ shape๋ฅผ ๋ถ๋ฆฌ์ํค๋๋ฐ ์ด์ฉํ ์ ์์ต๋๋ค.
What about circles?
SAT๋ก polygon์ ๋ํด circle์ ํ
์คํธํ๋ ๊ฒ์, ์กฐ๊ธ ๋ฏ์ค์ง๋ง ์ด๋ ๊ฒ ํฉ๋๋ค.
์ค์ํ ๊ฒ์, circle์ ์ด๋ ํ ๋ณ๋ ๊ฐ์ง๊ณ ์์ง ์์ผ๋ฏ๋ก
๋น์ ์ด ํ
์คํธ ํด์ผ ํ ๋๋ ทํ axis๊ฐ ์๋ค๋ ๊ฒ์
๋๋ค. ํ์ง๋ง, ํ
์คํธ ํ ํ์๊ฐ ์๋
'not so obvious'ํ ์ถ์ ์์ต๋๋ค.
์ด ์ถ์, circle์ ์ค์ฌ์์ polygon์ ๊ฐ์ฅ ๊ฐ๊น์ด ๊ผญ์ง์ ๊น์ง๋ฅผ ์๋ ์ถ์
๋๋ค.
๊ทธ ๋ค์๋ถํฐ๋, polygon์ ๋ชจ๋ (๋ณ์๋ํ)์ถ์ ์ํํ๋ฉด์, overlap์ ์ฒดํฌํ๋ฉด ๋ฉ๋๋ค.
์ฐธ๊ณ ๋ก, circle์ axis์ projectํ๋ ๋ฐฉ๋ฒ์, ์ค์ฌ์ projection ํ๋ค์ ๋ฐ์ง๋ฆ ๊ธธ์ด๋ฅผ ๋ํ๊ณ ๋นผ๋ฉด ๋ฉ๋๋ค.
Pro’s and Con’s
๋ค๋ฅธ ๋ชจ๋ collision detection ๊ธฐ๋ฒ์ฒ๋ผ, SAT ๋ํ ์ฅ,๋จ์ ์ด ์์ต๋๋ค. ๋ํ์ ์ธ ๊ฒ๋ค์
๋ค์๊ณผ ๊ฐ์ต๋๋ค.
Pros
- ๋น ๋ฅด๋ค - ๊ฝค ๊ฐ๋จํ vector ๊ณ์ฐ์ด๊ณ , (์ถฉ๋๊ฐ์ง๋ง์ด ๋ชฉ์ ์ด๋ผ๋ฉด) gap์ด ๋ฐ๊ฒฌ๋์๋ง์ ํ ์คํธ๋ฅผ ๋ง์น ์ ์๊ธฐ ๋๋ฌธ์, ๋ถํ์ํ ๊ณ์ฐ์ ์์จ ์๋ ์๋ค.
- ์ ํํ๋ค - (ํ์๊ฐ ์๋ ํ..)
Cons
- ๋ณผ๋ก๋ค๊ฐํ(Convex Polygon) ์ ๋ํด์๋ง ์ ์ฉ ๊ฐ๋ฅํ๋ค.
-> ๊ทธ๋ ์ง ์์ ์์ฃผ ๋ณต์กํ shape์ผ ๊ฒฝ์ฐ์๋, ๊ทธ๊ฒ์ ๋ค์ ๋ ์์ convex shape๋ก ์ชผ๊ฐ ๋ค์ ๊ฐ shape์ ๋ํด ํ ์คํธ ํด์ผํ๋ค. - ์ด๋ค ๋ณ์ด touching ํ๊ณ ์๋์ง๋ ์๋ ค์ฃผ์ง ์๋๋ค.-> ์ค์ง ์ผ๋ง๋ ๋ง์ด overlap ๋์ด์๊ณ , ์ด๋ฅผ ๋ถ๋ฆฌ์ํฌ ์ ์๋ ๊ฐ์ฅ ์งง์ distance๋ง ์๋ ค์ค ๋ฟ์ด๋ค.
-๋๊ธ ์ง์ -
I had a quick look at the implementation you posted. It appears to be checking for a collision only, and not actually figuring out how to separate them. If you were to use the ‘axis’ property directly after that method you would always get the last axis that was tested, which is not necessarily the the shortest path of separation.
To get the right axis, you would have to keep track of which axis had the shortest amount of overlap. This should be as simple as having another vector variable declared and checking it each time an axis is tested. If you get to the end and there is a collision, simply use the vector you have stored for the separation.
๋๊ธ
๋๊ธ ์ฐ๊ธฐ