ããŸããŸãªçç±ã§ãç¬èªã®ç©çãšã³ãžã³ã®äœæãéå§ã§ããŸãããŸããæ°åŠãç©çåŠãããã°ã©ãã³ã°ã®æ°ããç¥èã®éçºãšååã 次ã«ãç¬èªã®ç©çãšã³ãžã³ããäœæè
ãäœæã§ããæè¡çå¹æãåŠçã§ããŸãã ãã®å
¥éèšäºã§ã¯ãç¬èªã®ç©çãšã³ãžã³ããŒãããäœæããæ¹æ³ã玹ä»ããŸãã
ç©çåŠã¯ãã¬ã€ã€ãŒã«ã²ãŒã ã«æ²¡é ããããã®éæ¹ããªãæ©äŒãäžããŸãã ç©çãšã³ãžã³ããã¹ã¿ãŒããããšã¯ãããã°ã©ããŒã«ãšã£ãŠéåžžã«åœ¹ç«ã€ã¹ãã«ã«ãªããšæããŸãã ãšã³ãžã³ã®å
éšæäœãããæ·±ãç解ããããã«ããã€ã§ãæé©åãç¹æ®ãªæ©èœãäœæã§ããŸãã
ãã¥ãŒããªã¢ã«ã®ãã®ããŒãã§ã¯ã次ã®ãããã¯ã«ã€ããŠèª¬æããŸãã
- ç°¡åãªè¡çªæ€åº
- åçŽãªåçš®ã®çæ
- ã€ã³ãã«ã¹å解èœã匷å¶ãã
ããã«å°ããªãã¢ããããŸãïŒ
泚ïŒãã®ãã¥ãŒããªã¢ã«ã¯C ++ã§æžãããŠããŸãããã»ãŒãã¹ãŠã®ã²ãŒã éçºç°å¢ã§åãææ³ãšæŠå¿µã䜿çšã§ããŸãã
å¿
èŠãªç¥è
ãã®èšäºãç解ããã«ã¯ãæ°åŠãšå¹ŸäœåŠã«é¢ããååãªç¥èãå¿
èŠã§ãããããã°ã©ãã³ã°èªäœã¯ããã»ã©éèŠã§ã¯ãããŸããã ç¹ã«ã次ã®ãã®ãå¿
èŠã§ãã
- ãã¯ãã«æ°åŠã®åºæ¬ã®åºæ¬çãªç解
- 代æ°èšç®ãå®è¡ããæ©èœ
è¡çªèªè
ã€ã³ã¿ãŒãããã«ã¯è¡çªèªèã«é¢ããååãªèšäºãšãã¥ãŒããªã¢ã«ããããŸãã®ã§ããã®ãããã¯ã詳现ã«æ€èšããããšã¯ããŸããã
座æšè»žã«åãããå¢çç©åœ¢
座æšè»žã«æããããå¢çããã¯ã¹ïŒAxis Aligned Bounding BoxãAABBïŒã¯ã4ã€ã®è»žãé
眮ãããŠãã座æšç³»ã«æããããé·æ¹åœ¢ã§ãã ããã¯ãé·æ¹åœ¢ãå転ã§ãããåžžã«90床ã®è§åºŠã«ããããšãæå³ããŸãïŒéåžžã¯ç»é¢ã«åãããŠé
眮ãããŸãïŒã AABBã¯ä»ã®ããè€éãªåœ¢ç¶ãå¶éããããã«äœ¿çšããããããéåžžã¯ãå¢çããã¯ã¹ããšåŒã°ããŸãã
AABBã®äŸãè€éãªAABBã¯ãããè€éãªãã©ãŒã ãAABBå
ã§äº€å·®ã§ãããã©ããã確èªããããã®ç°¡åãªãã§ãã¯ãšããŠäœ¿çšã§ããŸãã ãã ããã»ãšãã©ã®ã²ãŒã ã®å ŽåãAABBã¯åºæ¬çãªåœ¢åŒãšããŠäœ¿çšãããå®éã«ã¯äœãå¶éããŸããã AABBã®æ§é ã¯éåžžã«éèŠã§ãã AABBãæå®ããæ¹æ³ã¯ããã€ããããŸãããããã«ç§ã®ãæ°ã«å
¥ãã瀺ããŸãã
struct AABB { Vec2 min; Vec2 max; };
ãã®åœ¢åŒã§ã¯ã2ã€ã®ãã€ã³ãã§AABBãæå®ã§ããŸãã ãã€ã³ãminã¯x軞ãšy軞ã«æ²¿ã£ãäžéã瀺ããmaxã¯äžéã瀺ããŸããã€ãŸããå·Šäžé
ãšå³äžé
ã瀺ããŸãã 2ã€ã®AABBã亀差ãããã©ãããå€æããã«
ã¯ãåé¢è»žå®çïŒSATïŒã®åºæ¬çãªç解ãå¿
èŠã§ãã
以äžã¯ãSATã䜿çšããChristopher Erickson
ãªã¢ã«ã¿ã€ã è¡çªæ€åºãµã€ãããã®ç°¡åãªãã§ãã¯ã§ãã
bool AABBvsAABB( AABB a, AABB b ) {
ãµãŒã¯ã«
åã¯ãååŸãšç¹ã«ãã£ãŠå®çŸ©ãããŸãã åæ§é ã¯æ¬¡ã®ããã«ãªããŸãã
struct Circle { float radius Vec position };
2ã€ã®åã®äº€å·®ã確èªããã®ã¯éåžžã«ç°¡åã§ãã2ã€ã®åã®ååŸãååŸããŠè¿œå ããåã®2ã€ã®äžå¿éã®è·é¢ã®åèšã倧ãããã©ããã確èªããŸãã
å¹³æ¹æ ¹æŒç®åãåãé€ãããã®éèŠãªæé©åïŒ
float Distance( Vec2 a, Vec2 b ) { return sqrt( (ax - bx)^2 + (ay - by)^2 ) } bool CirclevsCircleUnoptimized( Circle a, Circle b ) { float r = a.radius + b.radius return r < Distance( a.position, b.position ) } bool CirclevsCircleOptimized( Circle a, Circle b ) { float r = a.radius + b.radius r *= r return r < (ax + bx)^2 + (ay + by)^2 }
äžè¬ã«ãä¹ç®ã¯å€ã®å¹³æ¹æ ¹ãååŸãããããã¯ããã«å®äŸ¡ãªæŒç®ã§ãã
ã€ã³ãã«ã¹è§£å床ã匷å¶ãã
ã€ã³ãã«ã¹è§£æ±ºã¯ãç¹å®ã®ã¿ã€ãã®è¡çªè§£æ±ºæŠç¥ã§ãã è¡çªè§£æ±ºã¯ã亀差ãã2ã€ã®ãªããžã§ã¯ããååŸããŠå€æŽãã亀差ããªãããã«ããã¢ã¯ã·ã§ã³ã§ãã
äžè¬çãªå Žåãç©çãšã³ãžã³å
ã®ãªããžã§ã¯ãã«ã¯ã3ã€ã®åºæ¬çãª
èªç±åºŠ ïŒ2次å
ïŒããããŸããxyå¹³é¢å
ã®åããšå転ã§ãã ãã®èšäºã§ã¯ãæå³çã«å転ãå¶éããåã®ããAABBã®ã¿ã䜿çšãããããèæ
®ããå¿
èŠãããå¯äžã®èªç±åºŠã¯xyå¹³é¢å
ã®åãã§ãã
æ€åºãããè¡çªã解決ããããã»ã¹ã§ã¯ããªããžã§ã¯ããäºãã«äº€å·®ã§ããªãããã«ã移åã«ãã®ãããªå¶éã課ããŸãã åã®è¡åã解決ããåºæ¬çãªèãæ¹ã¯ãåã®è¡åïŒé床ã®ç¬éçãªå€åïŒã䜿çšããŠãè¡çªãèªèããããªããžã§ã¯ããåé¢ããããšã§ãã ãããè¡ãã«ã¯ãäœããã®æ¹æ³ã§åãªããžã§ã¯ãã®äœçœ®ãšé床ãèæ
®ããå¿
èŠããããŸããè¡çªæã«å°ããªãªããžã§ã¯ããšäº€å·®ãã倧ããªãªããžã§ã¯ããå°ã移åããå°ããªãªããžã§ã¯ãããããããé£ã³åºãããã«ããŸãã ãŸããç¡éã®è³ªéãæã€ãªããžã§ã¯ãããŸã£ããåããªãããã«ããããšèããŠããŸãã
åã®è¡åã解決ããããšã§éæã§ããããšã®ç°¡åãªäŸããã®å¹æãéæãããšåæã«ããªããžã§ã¯ãã®æ¯ãèãã®çŽæçãªç解ã«åŸãããã«ããœãªãããšå°ãã®æ°åŠã䜿çšããŸãã ãœãªããã¯ããŠãŒã¶ãŒïŒã€ãŸããéçºè
ïŒã«ãã£ãŠå®çŸ©ãããåçŽãªãã©ãŒã ã§ãããå€åœ¢äžèœãšããŠæ確ã«å®çŸ©ãããŠããŸãã ãã®èšäºã®AABBãšåã®äž¡æ¹ã¯å€åœ¢äžèœã§ãããåžžã«AABBãŸãã¯åã®ããããã«ãªããŸãã ãã¹ãŠã®å§çž®ãšã¹ãã¬ããã¯çŠæ¢ãããŠããŸãã
ãœãªããã䜿çšãããšãäžé£ã®èšç®ã倧å¹
ã«ç°¡çŽ åã§ããŸãã ãããã²ãŒã ã§ãœãªããããã䜿çšãããçç±ã§ãããããã£ãŠããã®èšäºã§ã¯ãœãªããã䜿çšããŸãã
ãªããžã§ã¯ããè¡çªããŸãã-次ã¯äœã§ããïŒ
2ã€ã®ç©äœã®è¡çªãèŠã€ãã£ããšããŸãã ããããåé¢ããæ¹æ³ã¯ïŒ è¡çªèªèã¯ã2ã€ã®éèŠãªç¹æ§ãæäŸãããšæ³å®ããŠããŸãã
åã®å¢ããäž¡æ¹ã®ãªããžã§ã¯ãã«é©çšããããããäºãã«æŒãé¢ãã«ã¯ãã©ã®æ¹åã«ã©ãã ãåçºãããããç¥ãå¿
èŠããããŸãã è¡çªæ³ç·ãšã¯ãåã®ã€ã³ãã«ã¹ãé©çšãããæ¹åã§ãã 浞éã®æ·±ãã¯ïŒä»ã®ããã€ãã®ãã©ã¡ãŒã¿ãŒãšäžç·ã«ïŒäœ¿çšãããåã®è¡æã®å€§ããã決å®ããŸãã ã€ãŸããèšç®ããå¿
èŠãããã®ã¯ãåã®éåéã®å€§ããã ãã§ãã
次ã«ãåã®éåéã®å€§ãããèšç®ããæ¹æ³ã詳ããèŠãŠã¿ãŸãããã 亀差ç¹ãæ€åºããã2ã€ã®ãªããžã§ã¯ãããå§ããŸãããã
åŒ1VAB=VBâVA
äœçœ®Aããäœçœ®Bãžã®ãã¯ãã«ãäœæããã«ã¯ã
endpoint - startpoint
å®è¡ããå¿
èŠãããããšã«æ³šæããŠãã ããã
VAB AããBãžã®çžå¯Ÿé床ã§ãããã®æ¹çšåŒã¯ãè¡çªã®æ³ç·ãåºæºã«ããŠè¡šçŸã§ããŸãã
n ãã€ãŸããè¡çªã®æ³ç·ã®æ¹åã«æ²¿ã£ãAããBãŸã§ã®çžå¯Ÿé床ãç¥ãããïŒ
åŒ2VAB cdotn=ïŒVBâVAïŒ cdotn
ããã§ã
ã¹ã«ã©ãŒç©ã䜿çšã
ãŸã ã ã¹ã«ã©ãŒç©ã¯ãã³ã³ããŒãã³ãããšã®ç©ã®åçŽãªåèšã§ãã
åŒ3V1= beginbmatrixx1y1 endbmatrixãV2= beginbmatrixx2y2 endbmatrixV1 cdotV2=x1âx2+y2ây2
次ã®ã¹ãããã¯
ã匟æ§ä¿æ°ã®æŠå¿µãå°å
¥ããããšã§ãã 匟æ§ã¯ã匟æ§ãæå³ããæŠå¿µã§ãã ç©çãšã³ãžã³ã®åãªããžã§ã¯ãã«ã¯åŒŸåæ§ãããã10é²æ°å€ã§è¡šãããŸãã ãã ããåã®éåéã®èšç®ã«ã¯1ã€ã®å°æ°å€ã®ã¿ã䜿çšãããŸãã
ç®çã®åŒŸåæ§ãéžæããã«ã¯
e ããã€ãã·ãã³ãïŒãçŽæçã«äºæ³ãããçµæãæºãããŠãããããé¢é£ããæå°ã®åŒŸæ§ã䜿çšããå¿
èŠããããŸãã
åãåã£ãããš
e ãåã®éåéã®å€§ãããèšç®ããããã®åŒã«ä»£å
¥ããããšãã§ããŸãã
ãã¥ãŒãã³ã®åŸ©å
ã®æ³åã¯æ¬¡ã®ããã«èªã¿ãŸãã
åŒ4Vâ²=eâV
è¡çªåŸã®é床ã¯ãè¡çªåã®é床ã«äžå®ã®å®æ°ãæãããã®ã«çãããšããã ãã§ãã ãã®å®æ°ã¯ãåçºä¿æ°ããè¡šããŸãã ãããç¥ã£ãŠããã°ãçŸåšã®æ¹çšåŒã§åŒŸæ§ãç°¡åã«çœ®ãæããããšãã§ããŸãã
åŒ5VAB cdotn=âeâïŒVBâVAïŒ cdotn
ããã«è² ã®å€ã衚瀺ãããŠããããšã«æ³šæããŠãã ããã ããã§ãã€ãã¹èšå·ãå°å
¥ããããšã«æ³šç®ããŠãã ããã ãã¥ãŒãã³ã®å埩ã®æ³åã«ãã
Vâ² ãåçºåŸã®çµæã®ãã¯ãã«ã¯ãå®éã«ã¯Vãšã¯å察ã®æ¹åã«é²ã¿ãŸããã§ã¯ãæ¹çšåŒã§å察ã®æ¹åãã©ã®ããã«è¡šçŸããã®ã§ããããã ãã€ãã¹èšå·ãå
¥åããŸãã
次ã«ãåã®ã€ã³ãã«ã¹ã®åœ±é¿äžã§ãããã®é床ãè¡šçŸããå¿
èŠããããŸãã ãã¯ãã«ãã¹ã«ã©ãŒã®éåéåã«å€æŽããããã®ç°¡åãªæ¹çšåŒã次ã«ç€ºããŸã
j ç¹å®ã®æ¹åã«
n ïŒ
åŒ6Vâ²=V+jân
ãã®æ¹çšåŒã¯éåžžã«éèŠãªã®ã§ç解ããŠãã ããã åäœãã¯ãã«ããããŸã
n æ¹åã瀺ããŸãã ã¹ã«ã©ãŒããããŸã
j ãã¯ãã«ã®é·ãã瀺ã
n ã ã¹ã±ãŒãªã³ã°ããããã¯ãã«ãåèšããå Žå
n ãš
V ç§ãã¡ã¯åŸã
Vâ² ã ããã¯åçŽã«2ã€ã®ãã¯ãã«ãå ç®ãããã®ã§ãããã®å°ããªæ¹çšåŒã䜿çšããŠã1ã€ã®ãã¯ãã«ã®åã®éåéãå¥ã®ãã¯ãã«ã«é©çšã§ããŸãã
ããã§ãããã¹ãããšãå°ããããŸãã æ£åŒã«ã¯ãå¢ãã®å¢ãã¯å¢ãã®å€åãšããŠå®çŸ©ãããŸãã éåéã¯
*
ã§ãã ãããç¥ã£ãŠã次ã®ããã«æ£åŒãªå®çŸ©ã«åŸã£ãŠè¡åãè¡šçŸã§ããŸãã
åŒ7ã€ã³ãã«ã¹=質éâé床é床= fracImpulsemass\ãããã£ãŠVâ²=V+ fracjânmass
äžè§åœ¢ã®åœ¢ç¶ã®3ã€ã®ç¹ïŒ
\ãããã£ãŠ ïŒããããã£ãŠããšèªãããšãã§ããŸãã ãã®æå®ã¯ãåã®ãã®ãã次ã®ãã®ã®ççãæšæž¬ããããã«äœ¿çšãããŸãã
é 調ã§ãïŒ ãã ããåã®å¢ãã次ã®ããã«è¡šçŸããå¿
èŠããããŸãã
j 2ã€ã®ç°ãªããªããžã§ã¯ãã«é¢é£ããŸãã ãªããžã§ã¯ãAãšãªããžã§ã¯ãBã®è¡çªäžããªããžã§ã¯ãAã¯Bãšã¯å察æ¹åã«åçºãããŸãã
åŒ8Vâ²A=VA+ fracjânmassAVâ²B=VBâ fracjânmassB
ãããã®2ã€ã®æ¹çšåŒã¯ãåäœæ¹åãã¯ãã«ã«æ²¿ã£ãŠBããAãã¯ãããŸã
n åã®éåéã®ã¹ã«ã©ãŒããšïŒé
n ïŒ
j ã
ããã¯ãã¹ãŠãåŒ8ãš5ãçµã¿åãããããã«å¿
èŠã§ããæçµçãªåŒã¯æ¬¡ã®ããã«ãªããŸãã
åŒ9ïŒVAâVV+ fracjânmassA+ fracjânmassBïŒân=âeâïŒVBâVAïŒ cdotn\ãããã£ãŠïŒVAâVV+ fracjânmassA+ fracjânmassBïŒân+eâïŒVBâVAïŒ cdotn=0
èŠããŠããå Žåãå
ã®ç®æšã¯å€ãåé¢ããããšã§ããããªããªããè¡çªã解決ããå¿
èŠãããæ¹åãããã£ãŠããããã§ãïŒè¡çªã®èªèã«ãã£ãŠæ±ºå®ãããŸãïŒããã®æ¹åã®å€ã決å®ããã ãã§ãã ç§ãã¡ã®å Žåãæªç¥ã®å€
j ; 匷調ããå¿
èŠããããŸã
j 圌女ã®æ¹çšåŒã解ããŸãã
åŒ10ïŒVBâVAïŒ cdotn+jâïŒ fracjânmassA+ fracjânmassBïŒân+eâïŒVBâVAïŒ cdotn=0\ãããã£ãŠïŒ1+eïŒïŒïŒVBâVAïŒ cdotnïŒ+jâïŒ fracjânmassA+ fracjânmassBïŒân=0\ãããã£ãŠj= fracâïŒ1+eïŒïŒïŒVBâVAïŒ cdotnïŒ frac1massA+ frac1massB
ãããŒãéåžžã«å€ãã®ã³ã³ãã¥ãŒãã£ã³ã°ïŒ ããããããã ãã§ãã å·ŠåŽã®åŒ10ã®æçµåœ¢ã§ã¯ã
j ïŒå€ïŒãããã³å³åŽã®ãã¹ãŠããã§ã«èªèãããŠããŸãã ããã¯ãæ°è¡ã®ã³ãŒããèšè¿°ããŠã¹ã«ã©ãŒã®éåéåãèšç®ã§ããããšãæå³ããŸã
j ã ãããŠããã®ã³ãŒãã¯æ°åŠè¡šèšãããã¯ããã«èªã¿ãããã§ãïŒ
void ResolveCollision( Object A, Object B ) {
ãã®ã³ãŒãäŸã«ã¯2ã€ã®éèŠãªåŽé¢ããããŸãã æåã«ã
if(VelAlongNormal > 0)
ã10è¡ç®ãèŠãŠãã ããã ãã®ãã§ãã¯ã¯éåžžã«éèŠã§ãããªããžã§ã¯ããäºãã«åãã£ãŠç§»åããå Žåã«ã®ã¿è¡çªãèš±å¯ããŸãã
2ã€ã®ãªããžã§ã¯ããè¡çªããŸããããé床ã次ã®ãã¬ãŒã ã§ããããåé¢ããŸãã ãã®ã¿ã€ãã®è¡çªã¯èš±å¯ãããŸããããªããžã§ã¯ããäºãã«å察æ¹åã«ç§»åããå ŽåãäœãããŸããã ãã®ãããå®éã«è¡çªããªããªããžã§ã¯ãã®è¡çªã¯è§£æ±ºããŸããã ããã¯ããªããžã§ã¯ããçžäºäœçšãããšãã«äœãèµ·ãããã«ã€ããŠã®çŽæçãªæåŸ
ãæºããã·ãã¥ã¬ãŒã·ã§ã³ãäœæããããã«éèŠã§ãã
第äºã«ãé質éãäœã®çç±ããªãèšç®ãããããšã¯æ³šç®ã«å€ããŸãã åãªããžã§ã¯ãå
ã«é質éãä¿æããåæã«äºåèšç®ããã®ãæåã§ãã
A.inv_mass = 1 / A.mass
å€ãã®ç©çãšã³ãžã³ã§ã¯ãæªåŠçã®è³ªéã¯å®éã«ã¯ä¿åãããŸããã å€ãã®å Žåãç©çãšã³ãžã³ã¯è³ªéã®éæ°ã®ã¿ãä¿åããŸãã ã»ãšãã©ã®æ°åŠçèšç®ã§ã¯ã
1/
圢åŒã®è³ªéã䜿çšãããŸãã
æåŸã«æ³šæãã¹ãããšã¯ãã¹ã«ã©ãŒã®å¢ããã€ã³ããªãžã§ã³ãã«åæ£ãããå¿
èŠããããšããããšã§ãã
j 2ã€ã®ãªããžã§ã¯ãã«ã 倧ããªãªããžã§ã¯ããã倧ããªãªããžã§ã¯ãããå°ããªãªããžã§ã¯ããé£ã³å»ãããã
j ã倧ããªãªããžã§ã¯ãã®é床ã¯ããããããªå²åã§å€åããŸã
j ã
ãããè¡ãã«ã¯ã次ã®ããšãå®è¡ã§ããŸãã
float mass_sum = A.mass + B.mass float ratio = A.mass / mass_sum A.velocity -= ratio * impulse ratio = B.mass / mass_sum B.velocity += ratio * impulse
ãã®ã³ãŒãã¯äžèšã®
ResolveCollision()
é¢æ°ã®äŸã«äŒŒãŠããããšã«æ³šæããããšãéèŠã§ãã äžã§èª¬æããããã«ãããã¯ãã¹ã¯ç©çãšã³ãžã³ã§éåžžã«åœ¹ç«ã¡ãŸãã
æ²æ²¡ç©
ãã§ã«èšè¿°ãããã³ãŒãã䜿çšãããšããªããžã§ã¯ãã¯è¡çªããäºãã«é£ã³å»ããŸãã ããã¯çŽ æŽãããããšã§ããããªããžã§ã¯ãã®1ã€ã«ç¡éã®è³ªéãããå Žåã¯ã©ããªããŸããïŒ ã·ãã¥ã¬ãŒã·ã§ã³ã§ç¡é質éãå®çŸ©ãã䟿å©ãªæ¹æ³ãå¿
èŠã«ãªããŸãã
ç¡é質éãšããŠãŒãã䜿çšããããšããå§ãããŸã-ãã ãã質éããŒãã®ãªããžã§ã¯ãã®é質éãèšç®ããããšãããšããŒãã§é€ç®ãããŸãã çžäºè³ªéã®èšç®ã«ããããã®åé¡ã®è§£æ±ºçã¯æ¬¡ã®ãšããã§ãã
if(A.mass == 0) A.inv_mass = 0 else A.inv_mass = 1 / A.mass
ããŒããã®å€ã¯ãåãã«ã¹ã解決ãããšãã«æ£ããèšç®ã«ã€ãªãããŸãã ããã¯ç§ãã¡ã«åã£ãŠããŸãã ãªããžã§ã¯ããæ²ãåé¡ã¯ããããªããžã§ã¯ããéåã«ãã£ãŠå¥ã®ãªããžã§ã¯ãã«ãæ²ã¿å§ããããšãã«çºçããŸãã äœåŒŸæ§ã®ç©äœãç¡éã®è³ªéã®å£ã«ã¶ã€ãããæ²ã¿å§ããããšããããŸãã
ãã®drãã¯ãæµ®åå°æ°ç¹èšç®ãšã©ãŒãåå ã§çºçããŸãã åæµ®åå°æ°ç¹ã®èšç®äžã«ãããŒããŠã§ã¢ã®å¶éã«ããå°ããªãšã©ãŒãè¿œå ãããŸãã ïŒè©³çŽ°ã«ã€ããŠã¯ãGoogleã®[æµ®åå°æ°ç¹ãšã©ãŒIEEE754]ãåç
§ããŠãã ãããïŒæéãçµã€ã«ã€ããŠããã®ãšã©ãŒã¯ããžã·ã§ãã³ã°ãšã©ãŒã«èç©ãããçžäºã«ãªããžã§ã¯ããownããŠããŸããŸãã
ãã®äœçœ®æ±ºã誀差ãä¿®æ£ããã«ã¯ããããèæ
®ããå¿
èŠãããããããç·åœ¢æ圱ããšåŒã°ããæ¹æ³ã玹ä»ããŸãã ããããªå²åã§ã®ç·åœ¢æ圱ã«ããã2ã€ã®ãªããžã§ã¯ãã®çžäºãžã®æµžéãæžå°ããŸãã åã€ã³ãã«ã¹ã®é©çšåŸã«å®è¡ãããŸãã äœçœ®ã®ä¿®æ£ã¯éåžžã«ç°¡åã§ãïŒåãªããžã§ã¯ããæ³ç·ã«æ²¿ã£ãŠè¡çªã«ç§»åããŸã
n 浞éçã«ããïŒ
void PositionalCorrection( Object A, Object B ) { const float percent = 0.2
penetrationDepth
ãã·ã¹ãã ã®ç·è³ªéã«ã¹ã±ãŒãªã³ã°
penetrationDepth
ããšã«æ³šæããŠãã ããã ããã«ããã質éã«æ¯äŸããäœçœ®è£æ£ãè¡ãããŸãã å°ããªãªããžã§ã¯ãã¯éããªããžã§ã¯ããããéãåçºããŸãã
ãã ãããã®å®è£
ã«ã¯å°ããªåé¡ããããŸããäœçœ®æ±ºããšã©ãŒãåžžã«è§£æ±ºããå Žåããªããžã§ã¯ãã¯äºãã®äžã«ããéãåžžã«éããŸãã ãžãã¿ãé€å»ããã«ã¯ãå°ããªèš±å®¹å€ãèšå®ããå¿
èŠããããŸãã 䟵å
¥ãç¹å®ã®ä»»æã®ãããå€ãè¶
ããå Žåã«ã®ã¿ä¿®æ£ãå®è¡ããŸããããããã¹ãããããšåŒã³ãŸãã
void PositionalCorrection( Object A, Object B ) { const float percent = 0.2
ããã«ãããäœçœ®è£æ£ãè¡ããã«ãªããžã§ã¯ããäºãã«å°ã貫éããããšãã§ããŸãã
åçŽãªåçš®ã®çæ
ãã®èšäºã®ãã®éšåã§æåŸã«æ€èšããã®ã¯ãåçŽãªå€æ§äœã®çæã§ãã æ°åŠã®
å€æ§æ§ã¯ãã空éã®é åãè¡šãç¹ã®éåãã®ãããªãã®ã§ãã ãã ããããã§ã¯ãå€æ§æ§ããšã¯ã2ã€ã®ãªããžã§ã¯ãéã®è¡çªã«é¢ããæ
å ±ãå«ãå°ããªãªããžã§ã¯ããæå³ããŸãã
æšæºçãªå€æ§äœå®£èšã¯æ¬¡ã®ããã«ãªããŸãã
struct Manifold { Object *A; Object *B; float penetration; Vec2 normal; };
è¡çªæ€åºäžã«ã䟵å
¥ãšè¡çªæ³ç·ãèšç®ããå¿
èŠããããŸãã ãã®æ
å ±ã決å®ããã«ã¯ãèšäºã®æåããå
ã®è¡çªèªèã¢ã«ãŽãªãºã ãæ¡åŒµããå¿
èŠããããŸãã
ãµãŒã¯ã«ãµãŒã¯ã«
æãåçŽãªã³ãªãžã§ã³ã¢ã«ãŽãªãºã ããµãŒã¯ã«ãµãŒã¯ã«ã³ãªãžã§ã³ããå§ããŸãããã ãã®ãã§ãã¯ã¯ãã£ãšç°¡åã§ãã çŽäºè§£æ±ºã®æ¹åæ§ãæ³åã§ããŸããïŒ ããã¯ãåAããåBãžã®ãã¯ãã«ã§ããäœçœ®Aããäœçœ®BãåŒãããšã§ååŸã§ããŸãã
䟵å
¥ã®æ·±ãã¯ãåã®ååŸãšåã®éã®è·é¢ã«é¢é£ããŠããŸãã åã®é¢ä»ãã¯ãåãªããžã§ã¯ããŸã§ã®è·é¢ã®ååŸã®åèšããæžç®ããããšã§èšç®ã§ããŸãã
次ã«ãåéè¡çªå€æ§äœçæã¢ã«ãŽãªãºã ã®å®å
šãªäŸã瀺ããŸãã
bool CirclevsCircle( Manifold *m ) {
ããã§ã¯ã次ã®ç¹ã«æ³šæãã䟡å€ããããŸããå¹³æ¹æ ¹èšç®ã¯å®è¡ããŸããããå¹³æ¹æ ¹èšç®ãªãã§å®è¡ã§ããŸãïŒãªããžã§ã¯ãã«è¡çªããªãå ŽåïŒãåã1ç¹ã«ãããã©ããã確èªããŸãã ããããåããã€ã³ãã«ããå Žåãè·é¢ã¯ãŒãã«ãªãã
t / d
èšç®ãããšãã«ãŒãã§é€ç®ããªãããã«ããå¿
èŠããããŸãã
AABB-AABB
AABB-AABBã®ãã¹ãã¯ãåãããå°ãè€éã§ãã è¡çªæ³ç·ã¯ãAããBãžã®ãã¯ãã«ã§ã¯ãªãããšããžã®æ³ç·ã«ãªããŸãã AABBã¯4ã€ã®ãšããžãæã€é·æ¹åœ¢ã§ãã åãšããžã«ã¯æ³ç·ããããŸãã ãã®æ³ç·ã¯ããšããžã«åçŽãªåäœãã¯ãã«ã瀺ããŸãã
2Dã®ç·ã®äžè¬æ¹çšåŒã調ã¹ãŸãã
ax+by+c=0normal= beginbmatrixab endbmatrix

äžèšã®æ¹çšåŒã§
a
ã
b
ãš
b
ã¯ã©ã€ã³ã®æ³ç·ãã¯ãã«ã§ããããã¯ãã«
(a, b)
ã¯æ£èŠåãããŠãããšèŠãªãããŸãïŒãã¯ãã«ã®é·ãã¯ãŒãã§ãïŒã è¡çªæ³ç·ïŒè¡çªè§£æ±ºã®æ¹åïŒã¯ãæ³ç·ã®ãšããžã®1ã€ã«åããããŸãã
ç·ã®äžè¬çãªæ¹çšåŒã§
c
ãäœãè¡šããŠãããç¥ã£ãŠããŸããïŒ
c
ã¯ãåç¹ãŸã§ã®è·é¢ã§ãã èšäºã®æ¬¡ã®éšåã§èŠãããã«ãããã¯ãã€ã³ããè¡ã®ã©ã¡ãåŽã«ãããã確èªããã®ã«éåžžã«äŸ¿å©ã§ãã
ããã§å¿
èŠãªã®ã¯ããããªããžã§ã¯ãã®ã©ã®ãšããžãå¥ã®ãªããžã§ã¯ããšè¡çªããããå€æããããšã§ãããã®åŸãæ³ç·ãååŸããŸãã ãã ãã2ã€ã®è§åºŠã亀差ããå Žåãªã©ã2ã€ã®AABBã®ããã€ãã®ãšããžã亀差ããå ŽåããããŸãã ããã¯
ãæå°æµžéã®è»žã決å®ããå¿
èŠãããããšãæå³ããŸãã
貫éã®2ã€ã®è»žã æ°Žå¹³æ¹åã®X軞ã¯è²«éãæãå°ãªã軞ãªã®ã§ããã®è¡çªã¯X軞ã«æ²¿ã£ãŠè§£æ±ºããå¿
èŠããããŸããAABB-AABBå€æ§äœãšè¡çªèªèãçæããããã®å®å
šãªã¢ã«ãŽãªãºã ã¯æ¬¡ã®ãšããã§ãã

bool AABBvsAABB( Manifold *m ) {
-AABB
æåŸã«æ€èšãããã¹ãã¯ããµãŒã¯ã«AABBãã§ãã¯ã§ããããã§ã®ã¢ã€ãã¢ã¯ãåã«æãè¿ããã€ã³ãAABBãèšç®ããããšã§ãããã®åŸããã§ãã¯ã¯åãšåã®ãã§ãã¯ã®ãããªãã®ã«åçŽåãããŸããæãè¿ãç¹ãèšç®ããè¡çªãèªèããåŸãæ³ç·ã¯åã®äžå¿ããæãè¿ãç¹ãžã®æ¹åã«ãªããŸãã浞é深床ã¯ãåã«æãè¿ãç¹ãŸã§ã®è·é¢ãšåã®ååŸã®å·®ã§ãã
亀差ç¹ã¹ããŒã AABBãµãŒã¯ã«ãããªãããŒãªç¹æ®ãªã±ãŒã¹ã1ã€ãããŸããåã®äžå¿ãAABBã®å
åŽã«ããå Žåã¯ãåã®äžå¿ãAABBã®æãè¿ã端ãŸã§åãåããæ³ç·ãåæ ããå¿
èŠããããŸãã bool AABBvsCircle( Manifold *m ) {
ãããã«
ç©çã·ãã¥ã¬ãŒã·ã§ã³ã«ã€ããŠããå°ãç解ã§ãããšæããŸãããã®ãã¥ãŒããªã¢ã«ã¯ãç¬èªã®ç©çãšã³ãžã³ã®äœæããŒãããå§ããã®ã«ååã§ãã次ã®éšåã§ã¯ãç©çãšã³ãžã³ã«å¿
èŠãªãã¹ãŠã®å¿
èŠãªæ¡åŒµãã€ãŸã以äžãæ€èšããŸãã- ã³ã³ã¿ã¯ããã¢ã®ãœãŒããšã¯ãªããã³ã°
- åºãäœçž
- ãã³ãã«
- çµ±å
- ããŒ
- å空éã®äº€å·®ç¹
- ã¢ãžã¥ãŒã«æ§ïŒææã質éã匷床ïŒ