рдореИрдВрдиреЗ рдЯрдХреНрдХрд░ рдорд╛рдиреНрдпрддрд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХрд╛ рдЕрдзреНрдпрдпрди рдХрд┐рдпрд╛, рдФрд░ рдЗрд╕рдиреЗ рдореБрдЭреЗ рдЧрд┐рд▓реНрдмрд░реНрдЯ-рдЬреЙрдирд╕рди-рдХреАрд░реНрдереА (GJK) рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рддрдХ рдкрд╣реБрдБрдЪрд╛рдпрд╛ред
рдкреЛрд╕реНрдЯ рдХреЗ рд╕рднреА рдХреЛрдб рдЙрджрд╛рд╣рд░рдг рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рд▓рд┐рдЦреЗ рдЧрдП рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдореИрдВ рдмрдирд╛рдИ рдЧрдИ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рдкреЛрд╕реНрдЯ рдореЗрдВ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдЪрд░реНрдЪрд╛ рдирд╣реАрдВ рдХреА рдЬрд╛рддреА рд╣реИрдВред рд╡реЗ рд╕рд░рд▓ рд╣реИрдВ рдФрд░ GitHub рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рджреЗрдЦреЗ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ:
рдкреЛрд╕реНрдЯ рд╕реЗ рд╕рднреА рдХреЛрдб GitHub рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реИрдВ:
https://github.com/jthomperoo/gjk-ts-implementationрдкреЛрд╕реНрдЯ рдХреЛ рдЗрд╕ рд▓реЗрдЦ рдФрд░ рдЙрд╕рдореЗрдВ рд╕реБрдЭрд╛рдП рдЧрдП рд╡реАрдбрд┐рдпреЛ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рдерд╛:
рдкрд░рд┐рдЪрдп
рдЬреАрдЬреЗрдХреЗ рдПрдХ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рд╣реИ рдЬрд┐рд╕реЗ рджреЛ рдЙрддреНрддрд▓ рдЖрдХреГрддрд┐рдпреЛрдВ рдХреЗ рдкреНрд░рддрд┐рдЪреНрдЫреЗрджрди рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдпрд╣ рдПрдХ рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд "рд╕рд╣рд╛рдпрдХ рдлрд╝рдВрдХреНрд╢рди" рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рд░рд▓ рдФрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬреЛ рдЖрдкрдХреЛ рдЕрдзрд┐рдХ рд╕рд╛рдорд╛рдиреНрдп рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ - рдЙрд╕реА рддрд░рд╣, рдЖрдк рдмрд╣реБрднреБрдЬ рдФрд░ рдЖрдХреГрддрд┐рдпреЛрдВ рд╕реЗ рдорд┐рд▓рдХрд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рджреАрд░реНрдШрд╡реГрддреНрддред
рдЖрд╡рд╢реНрдпрдХ рдЬрд╛рдирдХрд╛рд░реА
рдорд┐рдиреНрдХреЛрд╡рд╕реНрдХреА рдпреЛрдЧ
рдЬреАрдЬреЗрдХреЗ рдПрдХ рдЕрд╡рдзрд╛рд░рдгрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдорд┐рдВрдХреЛрд╡рд╕реНрдХреА рдпреЛрдЧ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдПрд╕рдПрдо рдХреА рдЧрдгрдирд╛ рджреЛ рдЖрдВрдХрдбрд╝реЛрдВ рдХреЗ рд╕рднреА рдмрд┐рдВрджреБрдУрдВ рдХреЛ рдЬреЛрдбрд╝рдХрд░ рдХреА рдЬрд╛рддреА рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдиреАрдЪреЗ рджрд┐рдЦрд╛рдП рдЧрдП рджреЛ рдЖрдВрдХрдбрд╝реЗ рд▓реЗрдВ:
рдЪрд┐рддреНрд░ A (рд╣рд░рд╛):рдЪрд┐рддреНрд░рд╛ рдмреА (рдмреИрдВрдЧрдиреА):рдЖрдХреГрддрд┐ A рдФрд░ рдЖрдХреГрддрд┐ B рдХреЗ рдорд╛рди рд▓реЗрддреЗ рд╣реБрдП, рд╣рдо Minkowski рд░рд╛рд╢рд┐ рдХреА рдЧрдгрдирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
A + D = (0,1) + (0,-1) = (0,0)
A + E = (0,1) + (1,1) = (1,2)
A + F = (0,1) + (-1,1) = (-1,2)
B + D = (1,-1) + (0,-1) = (1,-2)
B + E = (1,-1) + (1,1) = (2,0)
B + F = (1,-1) + (-1,1) = (0,0)
C + D = (-1,-1) + (0,-1) = (-1,-2)
C + E = (-1,-1) + (1,1) = (0,0)
C + F = (-1,-1) + (-1,1) = (-2,0)
рдпрджрд┐ рд╣рдо рдЗрди рдореВрд▓реНрдпреЛрдВ рдХреЛ рд▓реЗрддреЗ рд╣реИрдВ рдФрд░ рдЙрдирд╕реЗ рдПрдХ рдЧреНрд░рд╛рдл рдмрдирд╛рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рдХреМрди рд╕рд╛ рдЖрдВрдХрдбрд╝рд╛ рдкрд░рд┐рдгрд╛рдо рд╣реЛрдЧрд╛ред
рдЖрдВрдХрдбрд╝реЗ рдП рдФрд░ рдмреА рдХреЗ рд▓рд┐рдП рдорд┐рдВрдХреЛрд╡реНрд╕реНрдХреА рдпреЛрдЧ:рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рддрд╛рд▓рд┐рдХрд╛ рдФрд░ рдЧреНрд░рд╛рдлрд╝ рдореЗрдВ AD A + D рд╕реЗ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИрдорд┐рдВрдХреЛрд╡реНрд╕реНрдХреА рд░рд╛рд╢рд┐ рдХреЛ рдмреЗрд╣рддрд░ рдврдВрдЧ рд╕реЗ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдХрд▓реНрдкрдирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╣рдо рдПрдХ рдЖрдХреГрддрд┐ рдП рд▓реЗрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ рдмреА рдХреА рд░реВрдкрд░реЗрдЦрд╛ рдХреЗ рд╕рд╛рде рдмрд╛рдпрдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВред рдкрд░рд┐рдгрд╛рдореА рдЖрдХреГрддрд┐ рдорд┐рдиреНрдХреЛрд╡рд╕реНрдХреА рдпреЛрдЧ рд╣реЛрдЧреАред
рдорд┐рдВрдХреЛрд╡реНрд╕реНрдХреА рдЕрдВрддрд░
GJK Minkowski рд░рд╛рд╢рд┐ рдХрд╛ рднрд┐рдиреНрдирддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ A + B рдирд╣реАрдВ рд▓рд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди A - B. рдореЗрд░реЗ рджреНрд╡рд╛рд░рд╛ рдкрдврд╝реЗ рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рд╕реНрд░реЛрддреЛрдВ рдореЗрдВ, рдЗрд╕реЗ "Minkowski рдЕрдВрддрд░" рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдорд┐рдиреНрдХреЛрд╡рд╕реНрдХреА рдЕрдВрддрд░ рдореЗрдВ рдПрдХ рджрд┐рд▓рдЪрд╕реНрдк рд╕рдВрдкрддреНрддрд┐ рд╣реИ: рдпрджрд┐ рджреЛ рдЖрдВрдХрдбрд╝реЗ рдУрд╡рд░рд▓реИрдк / рдЗрдВрдЯрд░рд╕реЗрдХреНрдЯ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рдорд┐рдиреНрдХреЛрд╡рд╕реНрдХреА рдЕрдВрддрд░ рдореЗрдВ рдореВрд▓ рд╢рд╛рдорд┐рд▓ рд╣реЛрдЧрд╛ред рдФрд░ рдпрд╣ GJK рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХрд╛ рдЖрдзрд╛рд░ рд╣реИред
рдЖрдВрдХрдбрд╝реЗ рдП рдФрд░ рдмреА рдХреЗ рдореВрд▓реНрдпреЛрдВ рдХреЛ рд▓реЗрддреЗ рд╣реБрдП, рд╣рдо рдорд┐рдВрдХреЛрд╡рд╕реНрдХреА рдЕрдВрддрд░ рдХреА рдЧрдгрдирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
A - D = (0,1) - (0,-1) = (0,2)
A - E = (0,1) - (1,1) = (-1,0)
A - F = (0,1) - (-1,1) = (1,0)
B - D = (1,-1) - (0,-1) = (-1,0)
B - E = (1,-1) - (1,1) = (0,-2)
B - F = (1,-1) - (-1,1) = (2,-2)
C - D = (-1,-1) - (0,-1) = (-1,0)
C - E = (-1,-1) - (1,1) = (-2,-2)
C - F = (-1,-1) - (-1,1) = (0,-2)
рдпрджрд┐ рд╣рдо рдЗрди рдореВрд▓реНрдпреЛрдВ рдХреЛ рд▓реЗрддреЗ рд╣реИрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдЧреНрд░рд╛рдл рдкрд░ рдбрд╛рд▓рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдкрд░рд┐рдгрд╛рдореА рдЖрдХреГрддрд┐ рджреЗрдЦреЗрдВрдЧреЗред
рдЖрдВрдХрдбрд╝реЗ рдП рдФрд░ рдмреА рдХреЗ рд▓рд┐рдП рдорд┐рдВрдХреЛрд╡реНрд╕реНрдХреА рдЕрдВрддрд░:рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ AD рдФрд░ рдЧреНрд░рд╛рдл A - D рдХреЛ рд╕рдВрджрд░реНрднрд┐рдд рдХрд░рддрд╛ рд╣реИрдПрд▓реНрдЧреЛрд░рд┐рдереНрдо
рдЗрди рдЕрд╡рдзрд╛рд░рдгрд╛рдУрдВ рдХреЗ рдЖрдзрд╛рд░ рдкрд░, GJK рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдЙрдирдХрд╛ рдЕрдиреБрдХреВрд▓рди рдХрд░рддрд╛ рд╣реИред Minkowski рд░рд╛рд╢рд┐ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдореЗрдВ рдмрд╣реБрдд рд╕рдордп рд▓рдЧ рд╕рдХрддрд╛ рд╣реИ, рдЦрд╛рд╕рдХрд░ рдпрджрд┐ рдЖрдк рдХрдИ рдмрд┐рдВрджреБрдУрдВ рд╕реЗ рдпреБрдХреНрдд рджреЛ рдЖрдВрдХрдбрд╝реЛрдВ рдХреЗ рдкреНрд░рддрд┐рдЪреНрдЫреЗрджрди рдХреА рдЬрд╛рдВрдЪ рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП, GJK рджреЛ рдкреНрд░рдореБрдЦ рдЕрд╡рдзрд╛рд░рдгрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ: рд╕рд╣рд╛рдпрдХ рдХрд╛рд░реНрдп рдФрд░ рд╕рд┐рдореНрдкреНрд▓реЗрдХреНрд╕ред
рд╣реЗрд▓реНрдкрд░ рдХрд╛рд░реНрдп
рд╕рд╣рд╛рдпрдХ рдХрд╛рд░реНрдп рдкреВрд░реЗ рдЖрдВрдХрдбрд╝реЗ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд┐рдП рдмрд┐рдирд╛ рдорд┐рдВрдХреЛрд╡реНрд╕реНрдХреА рдЕрдВрддрд░ рдХреЗ рдХрд┐рдирд╛рд░реЗ рдкрд░ рдПрдХ рдмрд┐рдВрджреБ рдХрд╛ рдирдореВрдирд╛ рд▓реЗрдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рд╣реИред рд╣реЗрд▓реНрдкрд░ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рджреЛ рддреБрд▓рдирд╛рддреНрдордХ рдЖрдВрдХрдбрд╝реЗ рдорд┐рд▓рддреЗ рд╣реИрдВ, рдФрд░ рдЬрд┐рд╕ рджрд┐рд╢рд╛ рдХреЛ рдЬрд╛рдВрдЪрдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рддрдм рд╕рд╣рд╛рдпрдХ рдлрд╝рдВрдХреНрд╢рди рдкреНрд░рддреНрдпреЗрдХ рдЖрдХреГрддрд┐ рд╕реЗ рджреЛ рд╡рд┐рдкрд░реАрдд рджрд┐рд╢рд╛рдУрдВ рд╕реЗ рдПрдХ рдмрд┐рдВрджреБ рджреВрд░ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИред рдЗрди рджреЛ рд╕рдмрд╕реЗ рджреВрд░ рдмрд┐рдВрджреБрдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рдЖрдк рдорд┐рдВрдХреЛрд╡реНрд╕реНрдХреА рдЕрдВрддрд░ рдХреЗ рдЖрдВрдХрдбрд╝реЗ рдкрд░ рд╕рд╣рд╛рдпрдХ рдмрд┐рдВрджреБ рдХреА рдЧрдгрдирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╣рдо рд╡рд┐рдкрд░реАрдд рджрд┐рд╢рд╛рдУрдВ рд╕реЗ рдЕрдВрдХ рд▓реЗрддреЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рд╣рдореЗрдВ рдорд┐рдВрдХреЛрд╡рд╕реНрдХреА рдЕрдВрддрд░ рдкрд░ рдПрдХ рдмрд┐рдВрджреБ рдорд┐рд▓рддрд╛ рд╣реИ, рдЬреЛ рд╣рдореЗрдВ рд╕рдмрд╕реЗ рдмрдбрд╝рд╛ рдХреНрд╖реЗрддреНрд░ рджреЗрдЧрд╛, рдЕрд░реНрдерд╛рддреН, рдПрдХ рдЙрдЪреНрдЪ рд╕рдВрднрд╛рд╡рдирд╛ рд╣реЛрдЧреА рдХрд┐ рд╣рдо рдЖрдВрдХрдбрд╝реЗ рдореЗрдВ рдореВрд▓ рдХреЛ рдШреЗрд░ рд▓реЗрдВрдЧреЗред рдЪреВрдБрдХрд┐ Minkowski рдЕрдВрддрд░
a - b
, рд╡рд┐рдкрд░реАрдд рджрд┐рд╢рд╛ рд╕реЗ рдкреНрд░рддрд┐рд░реВрдкрд┐рдд b рдХрд╛ рдмрд┐рдВрджреБ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рд╣рдореЗрдВ рдПрдХ рд╕рд╣рд╛рдпрдХ рдмрд┐рдВрджреБ рджреЗрдЧрд╛ рдЬреЛ рдЗрд╕ рджрд┐рд╢рд╛ рдореЗрдВ рдпрдерд╛рд╕рдВрднрд╡ рджреВрд░ рд╣реИред
рд╣реЗрд▓реНрдкрд░ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИ:
function support(a: IShape, b: IShape, direction: Vector): Vector { const aFar = a.FarthestPointInDirection(direction); const bFar = b.FarthestPointInDirection(direction.Invert()); return aFar.Sub(bFar); }
GJK рдХреЗ рдлрд╛рдпрджреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдпрд╣ рд╣реИ рдХрд┐
FarthestPointInDirection
рдХреЛ рдПрдмреНрд╕реНрдЯреНрд░реИрдХреНрдЯ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рдкреЙрд▓реАрдЧреЙрди рдФрд░ рдХрд░реНрд╡реНрд╕ рдкрд░ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпрд╣рд╛рдБ рдмрд╣реБрднреБрдЬ рдХреЗ рд▓рд┐рдП
FarthestPointInDirection
рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИред
class Polygon implements IShape { public points: Vector[]; ... public FarthestPointInDirection(direction: Vector): Vector { let farthestDistance = -Infinity; // If there are no points, just return point 0,0 let farthestPoint: Vector = new Vector(0,0); for (const point of this.points) { const distanceInDirection = point.Dot(direction); if (distanceInDirection > farthestDistance) { farthestPoint = point; farthestDistance = distanceInDirection; } } return farthestPoint; } }
рдпрджрд┐ рдЖрдк рдпрд╣ рджреЗрдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХрд┐ рдЕрдиреНрдп рдЖрдХреГрддрд┐рдпреЛрдВ рдХреЛ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рддреЛ
рдЗрд╕ рдкреЛрд╕реНрдЯ рдХреЗ Git рднрдВрдбрд╛рд░ рдХреЛ рджреЗрдЦреЗрдВ , рдЬреЛ
Circle
рд▓рд┐рдП рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рдкрд░рд┐рдЪрдп рджреЗрддрд╛ рд╣реИред
рдпрд╣рд╛рдВ рдмрддрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рдП (рдмреА
) рджрд┐рд╢рд╛ рдореЗрдВ рд╕рд╣рд╛рдпрдХ рдмрд┐рдВрджреБ
( рдП) рдФрд░ рдмреА рдХреЗ рдЖрдВрдХрдбрд╝реЛрдВ рдХреА рдЧрдгрдирд╛ рдХреИрд╕реЗ рдХреА рдЬрд╛рдПрдЧреА:
- рдЖрдХреГрддрд┐ рдП рд╕реЗ рд╕рдмрд╕реЗ рджреВрд░ рдмрд┐рдВрджреБ рд▓реЗ рд▓реЛ; рдпрд╣ рдмрд┐рдВрджреБ рдмреА (1, -1) рдирд┐рдХрд▓рд╛ред (рдЖрдк рдЗрд╕рдХреА рдЧрдгрдирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреИрд╕рд╛ рдХрд┐ рдКрдкрд░ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХрд░рддрд╛ рд╣реИ, рдпрд╛ рдмрд╕ рдЗрд╕реЗ рдЧреНрд░рд╛рдл рдХреЛ рджреЗрдЦрдХрд░ рджреЗрдЦреЗрдВ)ред
- рдЖрдХреГрддрд┐ рдмреА рд╕реЗ рд╕рдмрд╕реЗ рджреВрд░ рдмрд┐рдВрджреБ рд▓реЗ рд▓реЛ; рдпрд╣ рдмрд┐рдВрджреБ F (-1, 1) рдирд┐рдХрд▓рд╛ред
- рдмреА - рдПрдл рдХреА рдЧрдгрдирд╛ рдХрд░реЗрдВ; рдпрд╣ рдмрд┐рдВрджреБ рдмреАрдПрдл (2, -2) рдирд┐рдХрд▓рд╛ - рдпрд╣ рд╕рд╣рд╛рдпрдХ рд╣реЛрдЧрд╛ред
simplices
рдПрдХ рд╕рд┐рдореНрдкреНрд▓реЗрдХреНрд╕, рдорд┐рдВрдХреЛрд╡реНрд╕реНрдХреА рдЕрдВрддрд░ рдЖрдХреГрддрд┐ рдХреЗ рд╕рд╛рде рдЕрдВрдХреЛрдВ рдХрд╛ рдПрдХ рдирдореВрдирд╛ рд╣реИред рд╕рд┐рдореНрдкреНрд▓реЗрдХреНрд╕ рдореЗрдВ рддреАрди рдмрд┐рдВрджреБ рддрдХ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред GJK рдЙрдирдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдПрдХ рдЯрдХреНрдХрд░ рдХреА рдШрдЯрдирд╛ рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдореВрд▓ рдХреЗ рдЪрд╛рд░реЛрдВ рдУрд░ рдПрдХ рддреНрд░рд┐рдХреЛрдг рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реИред
рд╕рд┐рдВрдкреНрд▓реЗрдХреНрд╕ рдирд┐рд░реНрдорд╛рдг
рд╕рд┐рдореНрдкрд▓реЗрдХреНрд╕ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рд╡рд┐рднрд┐рдиреНрди рджрд┐рд╢рд╛рдУрдВ рдореЗрдВ рд╕рд╣рд╛рдпрдХ рдмрд┐рдВрджреБрдУрдВ рдХреЛ рдЬреЛрдбрд╝рдХрд░ рдкреБрдирд░рд╛рд╡реГрддрд┐ рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдкреНрд░рддреНрдпреЗрдХ рд╕рд╣рд╛рдпрдХ рдмрд┐рдВрджреБ рдХреЛ рдПрдХ рдирдИ рджрд┐рд╢рд╛ рдореЗрдВ рдЗрдВрдЧрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рддрд╛рдХрд┐ рд╣рдо рдЬрд┐рддрдиреА рдЬрд▓реНрджреА рд╣реЛ рд╕рдХреЗ рдПрдХ рдореВрд▓ рдмрд┐рдВрджреБ рд╡рд╛рд▓реЗ рдПрдХ рд╕рд┐рдВрдкреНрд▓реЗрдХреНрд╕ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░ рд╕рдХреЗрдВред рдХрдард┐рдирд╛рдИ рдЙрд╕ рджрд┐рд╢рд╛ рдХреЛ рдЪреБрдирдиреЗ рдореЗрдВ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдЕрдЧрд▓рд╛ рд╕рд╣рд╛рдпрдХ рдмрд┐рдВрджреБ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рд╣реИред
рдЯрдХрд░рд╛рд╡ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдФрд░ рджрд┐рд╢рд╛ рдЪрдпрди
рдореВрд▓ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдмрд╕ рдПрдХ рд╕рд╣рд╛рдпрдХ рдлрд╝рдВрдХреНрд╢рди рдХреА рд╕рд╣рд╛рдпрддрд╛ рд╕реЗ рдПрдХ рд╕рд┐рдореНрдкреНрд▓реЗрдХреНрд╕ рдмрдирд╛рддрд╛ рд╣реИ, рдЬреЛ рдЖрдВрдХрдбрд╝реЗ рдореЗрдВ рдореВрд▓ рдХреЗ рдмрд┐рдВрджреБ рдХреЛ рдШреЗрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддрд╛ рд╣реИред рд╣рдо рдпрд╣ рд╕рдордЭ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЧрдгрдирд╛ рдХрд┐рдП рдЧрдП рд╕рд╣рд╛рдпрдХ рдмрд┐рдВрджреБ рдореВрд▓ рддрдХ рдкрд╣реБрдБрдЪрддреЗ рд╣реИрдВ рдпрд╛ рдирд╣реАрдВ, рдпрд╣ рдЬрд╛рдБрдЪрдиреЗ рд╕реЗ рдХреЛрдИ рдЯрдХрд░рд╛рд╡ / рдЪреМрд░рд╛рд╣рд╛ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рдпрджрд┐ рдРрд╕рд╛ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдореВрд▓ Minkowski рдЕрдВрддрд░ рдХреЗ рдмрд╛рд╣рд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП; рдЗрд╕рд▓рд┐рдП, рд╣рдо рдХрд╣ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХреЛрдИ рдЯрдХреНрдХрд░ / рдЪреМрд░рд╛рд╣рд╛ рдирд╣реАрдВ рд╣реИред
function Calculate(a: IShape, b: IShape): Collision | undefined { // Build a new Simplex for determining if a collision has occurred const simplex = new Simplex(); // Choose an arbitrary starting direction let direction: Vector | undefined = new Vector(0,1); // Get the first support point and add it to the simplex const initSupportPoint = support(a, b, direction); simplex.Add(initSupportPoint); // Flip the direction for the next support point direction = direction.Invert(); // Keep iterating until the direction is undefined, this will occur when //
рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреА рд╕рднреА рдЬрдЯрд┐рд▓рддрд╛ рдФрд░ рдЖрдВрддрд░рд┐рдХ рдСрдкрд░реЗрд╢рди
simplex.CalculateDirection
ред
simplex.CalculateDirection
ред рдпрд╣ рдлрд╝рдВрдХреНрд╢рди рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдореВрд▓ рд╡рд░реНрддрдорд╛рди рд╕рд┐рдореНрдкреНрд▓реЗрдХреНрд╕ рдореЗрдВ рд╣реИ - рдпрджрд┐ рд╣рд╛рдВ, рддреЛ рдпрд╣
undefined
рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рдПрдЧрд╛; рдЕрдиреНрдпрдерд╛, рдпрд╣ рдПрдХ рд╕рд╣рд╛рдпрдХ рдмрд┐рдВрджреБ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдирдИ рджрд┐рд╢рд╛ рд▓реМрдЯрд╛рдПрдЧрд╛, рдЬрд┐рд╕реЗ рд╕рд┐рдореНрдкреНрд▓реЗрдХреНрд╕ рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
class Simplex { private points: Vector[]; ... CalculateDirection(): Vector | undefined { // Get a, the last point added to the simplex const a = this.points[this.points.length - 1]; // Since a was just added, we know that the inverse of a points // towards the origin const ao = a.Invert(); // If the simplex is a triangle if (this.points.length == 3) { // B is the penultimate in the simplex // C is the oldest point in the simplex const b = this.points[1]; const c = this.points[0]; // Determine a->b and a->c lines const ab = b.Sub(a); const ac = c.Sub(a); // Determine perpendicular of the a->b line let abPerp = new Vector(ab.y, -ab.x); // Check the handedness of the perpendicular, it should // face AWAY from the simplex if (abPerp.Dot(c) >= 0) { abPerp = abPerp.Invert(); } // If the origin lies outside of the simplex remove the // point and determine a new direction in the direction // of the perpendicular; aiming to try to encapsulate // the origin that lies outside if (abPerp.Dot(ao) > 0) { this.points.splice(0, 1); return abPerp; } // Determine perpendicular of the a->c line let acPerp = new Vector(ac.y, -ac.x); // Check the handedness of the perpendicular, it should // face AWAY from the simplex if (acPerp.Dot(b) >= 0) { acPerp = acPerp.Invert(); } // If the origin lies outside of the simplex remove the // point and determine a new direction in the direction // of the perpendicular; aiming to try to encapsulate // the origin that lies outside if (acPerp.Dot(ao) > 0) { this.points.splice(1, 1); return acPerp; } return undefined; } // Otherwise the simplex is just a line // B is the penultimate point in the simplex, // in this case the other end of the line const b = this.points[0]; // Determine a -> b line const ab = b.Sub(a); // Get the perpendicular of the a->b line let abPerp = new Vector(ab.y, -ab.x); // Check the handedness of the perpendicular, it should // face TOWARDS the origin if (abPerp.Dot(ao) <= 0) { abPerp = abPerp.Invert(); } return abPerp; } }
рдЖрдк рдЖрд╢реНрдЪрд░реНрдпрдЪрдХрд┐рдд рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ: рд╣рдо рдмреАрд╕реА рдЦрдВрдб рдХреА рдЬрд╛рдВрдЪ рдХреНрдпреЛрдВ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ? рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рдмрд┐рдирд╛ рд╢рд░реНрдд рдмрд╛рд╣рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдореВрд▓ рдЗрд╕рдХреЗ рд▓рдВрдмрд╡рдд рдХреЗ рд╕рд╛рде рд╣реИред рдЪреВрдВрдХрд┐ рдЕрдВрдХ рдмреА рдФрд░ рд╕реА рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕рд░рд▓ рд╣реИрдВ, рдФрд░ рдЙрдиреНрд╣реЗрдВ рди рдХреЗрд╡рд▓ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рд╣реИ, рд╣рдо рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдЙрдиреНрд╣реЗрдВ рдкрд┐рдЫрд▓реЗ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдореЗрдВ рдЬрд╛рдВрдЪрд╛ рдЧрдпрд╛ рдерд╛ред рдЙрдиреНрд╣реЗрдВ рдпрд╛ рддреЛ рдПрдХ рддреНрд░рд┐рдХреЛрдг рдХреЗ рд╣рд┐рд╕реНрд╕реЗ рдХреЗ рд░реВрдк рдореЗрдВ рдпрд╛ рдПрдХ рд╕рд┐рдореНрдкреНрд▓реЗрдХреНрд╕ рдореЗрдВ рдкрд╣рд▓реЗ рджреЛ рдмрд┐рдВрджреБрдУрдВ рдХреЗ рдПрдХ рдЦрдВрдб рдХреЗ рд░реВрдк рдореЗрдВ рдЬрд╛рдВрдЪрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ - рдЗрд╕рд╕реЗ рдХреЛрдИ рдлрд░реНрдХ рдирд╣реАрдВ рдкрдбрд╝рддрд╛ред рдЗрд╕рд▓рд┐рдП, рд╣рдо рд╕реБрд░рдХреНрд╖рд┐рдд рд░реВрдк рд╕реЗ рдмреАрд╕реА рд╕реЗрдЧрдореЗрдВрдЯ рдХреА рдЬрд╛рдВрдЪ рдХреЛ рдЫреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред
рд╡рд┐рд╕реНрддреГрдд рд╡рд┐рд╡рд░рдг
рд╣рдореЗрдВ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдХреЛрдб рдорд┐рд▓реЗ, рдФрд░ рдпрд╣ рднреНрд░рд╛рдордХ рд▓рдЧрддрд╛ рд╣реИред рдиреАрдЪреЗ рдореИрдВ рдКрдкрд░ рджрд┐рдЦрд╛рдП рдЧрдП рдЖрдВрдХрдбрд╝реЛрдВ рдП рдФрд░ рдмреА рдХреЗ рд▓рд┐рдП рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХреЗ рдЪрд░рдгреЛрдВ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░реВрдВрдЧрд╛ред
рдЕрдВрдХ рдП рдФрд░ рдмреА рдХреЗ рдЕрдВрдХ:- рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХреА рддреИрдпрд╛рд░реА; рд╣рдо рдкреНрд░рд╛рд░рдВрднрд┐рдХ рджрд┐рд╢рд╛ рдХреЗ рд░реВрдк рдореЗрдВ
(0,1)
рд▓реЗрддреЗ рд╣реИрдВред
// Build a new Simplex for determining if a collision has occurred const simplex = new Simplex(); // Choose an arbitrary starting direction let direction: Vector | undefined = new Vector(0,1);
- рд╣рдореЗрдВ рдкрд╣рд▓рд╛ рд╕рд╣рд╛рдпрдХ рдмрд┐рдВрджреБ рдорд┐рд▓рддрд╛ рд╣реИред
// Get the first support point and add it to the simplex const initSupportPoint = support(a, b, direction); simplex.Add(initSupportPoint); // Flip the direction for the next support point direction = direction.Invert();
рд╣рдо рдмрд┐рдВрджреБ A рд╕реЗ рджрд┐рд╢рд╛ (0,1)
рдФрд░ рдмрд┐рдВрджреБ B рд╕реЗ рджрд┐рд╢рд╛ (0,-1)
рдореЗрдВ рд╕рдмрд╕реЗ рджреВрд░ рдХрд╛ рдмрд┐рдВрджреБ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред
aFar: (0,1)
рдФрд░ bFar: (0,-1)
рд╕рд╣рд╛рдпрдХ рдмрд┐рдВрджреБ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрди рдореВрд▓реНрдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред
рд╕рдорд░реНрдерди: aFar-bFar = (0,2)
function support(a: IShape, b: IShape, direction: Vector): Vector { const aFar = a.FarthestPointInDirection(direction); const bFar = b.FarthestPointInDirection(direction.Invert()); return aFar.Sub(bFar); }
- рд╣рдо рдЕрдЧрд▓реЗ рд╕рд╣рд╛рдпрдХ рдмрд┐рдВрджреБ рдХреЗ рд▓рд┐рдП рджрд┐рд╢рд╛ рдлреНрд▓рд┐рдк рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдирдП рд╕рд╣рд╛рдпрдХ рдмрд┐рдВрджреБ рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реБрдП рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред
рд╕рдорд░реНрдерди: (0,-3)
// Flip the direction for the next support point direction = direction.Invert(); // Keep iterating until the direction is undefined, this will occur when //
- рдЬрд╛рдВрдЪреЗрдВ рдХрд┐ рдХреНрдпрд╛ рд╕рд╣рд╛рдпрдХ рдмрд┐рдВрджреБ рдореВрд▓ рддрдХ рдкрд╣реБрдВрдЪ рдЧрдпрд╛ рд╣реИ; рдпрджрд┐ рдирд╣реАрдВ, рддреЛ рдХреЛрдИ рдЪреМрд░рд╛рд╣рд╛ рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрджрд┐ рд╡рд╣ рдореВрд▓ рддрдХ рдкрд╣реБрдВрдЪ рдЧрдИ, рддреЛ рдмрд┐рдВрджреБ рдХреЛ рд╕рд┐рдореНрдкреНрд▓реЗрдХреНрд╕ рдореЗрдВ рдЬреЛрдбрд╝реЗрдВред
рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╕рд╣рд╛рдпрдХ рдмрд┐рдВрджреБ рдореВрд▓ рддрдХ рдкрд╣реБрдВрдЪ рдЧрдпрд╛ рд╣реИред
рджрд┐рд╢рд╛: (0,-1)
рд╕рдорд░реНрдерди: (0,-3)
supportPoint.Dot (рджрд┐рд╢рд╛): 3
// If the support point did not reach as far as the origin, // the simplex must not contain the origin and therefore there is no // intersection if (supportPoint.Dot(direction!) <= 0) { // No intersection return; } // Add the simplex and determine a new direction simplex.Add(supportPoint);
- рдЗрд╕ рд╕реНрддрд░ рдкрд░, рд╕рд┐рдореНрдкреНрд▓реЗрдХреНрд╕ рдПрдХ рд╕реЗрдЧрдореЗрдВрдЯ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрд╕рдореЗрдВ рдЕрдВрджрд░ рдХрд╛ рдореВрд▓ рдмрд┐рдВрджреБ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ; рдПрдХ рдирдИ рджрд┐рд╢рд╛ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рд╕рдореЗрдВ рд╕рд╣рд╛рдпрдХ рдмрд┐рдВрджреБ рдХреЛ рджреЗрдЦрдирд╛ рд╣реИред
direction = simplex.CalculateDirection();
- рд╣рдо рд╕рд┐рдореНрдкреНрд▓реЗрдХреНрд╕ рдореЗрдВ рдЬреЛрдбрд╝реЗ рдЧрдП рдЕрдВрддрд┐рдо рдмрд┐рдВрджреБ рдХреЛ рд▓реЗрддреЗ рд╣реИрдВ рдФрд░ рдореВрд▓ рдХреА рджрд┐рд╢рд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдпрд╣ рдЗрд╕ рдмрд┐рдВрджреБ рдХрд╛ рдкрд╛рд░рд╕реНрдкрд░рд┐рдХ рд╣реЛрдЧрд╛ред
a: (0,-3)
ao: (0,3)
CalculateDirection(): Vector | undefined { // Get a, the last point added to the simplex const a = this.points[this.points.length - 1]; // Since a was just added, we know that the inverse of a points // towards the origin const ao = a.Invert(); // If the simplex is a triangle if (this.points.length == 3) {
- рдЪреВрдВрдХрд┐ рд╕рд┐рдореНрдкреНрд▓реЗрдХреНрд╕ рдПрдХ рдЦрдВрдб рд╣реИ, рдПрдХ рддреНрд░рд┐рдХреЛрдг рдирд╣реАрдВ рд╣реИ, рд╣рдо рд╕реЗрдЧрдореЗрдВрдЯ рдХреЗ рджреВрд╕рд░реЗ рдмрд┐рдВрджреБ рдХреЛ рд▓реЗрддреЗ рд╣реИрдВ рдФрд░ рд╕рд┐рдореНрдкреНрд▓реЗрдХреНрд╕ рдХреЗ рд╕реЗрдЧрдореЗрдВрдЯ рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВред
b: (0,2)
ab: (0,5)
// Otherwise the simplex is just a line // B is the penultimate point in the simplex, // in this case the other end of the line const b = this.points[0]; // Determine a -> b line const ab = b.Sub(a);
- рд╣рдо рдЗрд╕ рд╕реЗрдЧрдореЗрдВрдЯ рдХреЗ рд▓рд┐рдП рд▓рдВрдмрд╡рдд рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рдореВрд▓ рдХреЗ рд▓рд┐рдП рдирд┐рд░реНрджреЗрд╢рд┐рдд рд╣реИред рдпрд╣ рдЕрдЧрд▓реЗ рд╕рд╣рд╛рдпрдХ рдмрд┐рдВрджреБ рдХреЗ рд▓рд┐рдП рдирдИ рджрд┐рд╢рд╛ рд╣реЛрдЧреАред
abPerp: (5, 0)
abPerp.Dot (ao) 0
abPerp: (-5, 0)
// Get the perpendicular of the a->b line let abPerp = new Vector(ab.y, -ab.x); // Check the handedness of the perpendicular, it should // face TOWARDS the origin if (abPerp.Dot(ao) <= 0) { abPerp = abPerp.Invert(); } return abPerp;
- рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЕрдЧрд▓реЗ рд╕рд╣рд╛рдпрдХ рдмрд┐рдВрджреБ рдХреА рдЦреЛрдЬ рдХрд░рдиреЗ рдХреА рджрд┐рд╢рд╛ рд╣реИред рд╣рдо рдЪрдХреНрд░ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рд▓реМрдЯрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ рдмрд╛рд╣рд░ рдирд╣реАрдВ рдирд┐рдХрд▓рддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рджрд┐рд╢рд╛ рд╣реИ, рдФрд░ рдЪреМрд░рд╛рд╣рд╛ рдЕрднреА рддрдХ рдирд╣реАрдВ рдорд┐рд▓рд╛ рд╣реИред
рджрд┐рд╢рд╛: (-5, 0)
рд╕рдорд░реНрдерди: (-2,-2)
supportPoint.Dot (рджрд┐рд╢рд╛): 10
рд╕рд╣рд╛рдпрдХ рдмрд┐рдВрджреБ рдореВрд▓ рддрдХ рдкрд╣реБрдВрдЪ рдЧрдпрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдпрд╣ рдирд╣реАрдВ рдХрд╣ рд╕рдХрддреЗ рдХрд┐ рдХреЛрдИ рдЪреМрд░рд╛рд╣рд╛ рдирд╣реАрдВ рд╣реИред
while(direction) { const supportPoint = support(a, b, direction); // If the support point did not reach as far as the origin, // the simplex must not contain the origin and therefore there is no // intersection if (supportPoint.Dot(direction!) <= 0) { // No intersection return; }
- рдПрдХ рддреНрд░рд┐рднреБрдЬ рдмрдирд╛рддреЗ рд╣реБрдП, рд╕рд┐рдореНрдкреНрд▓реЗрдХреНрд╕ рдореЗрдВ рдПрдХ рдирдпрд╛ рд╕рд╣рд╛рдпрдХ рдмрд┐рдВрджреБ рдЬреЛрдбрд╝реЗрдВред рдЗрд╕ рддреНрд░рд┐рдХреЛрдг рдореЗрдВ рдореВрд▓ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдпрджрд┐ рдРрд╕рд╛ рд╣реИ, рддреЛ рд╕рд┐рдореНрдкреНрд▓реЗрдХреНрд╕
undefined
рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рдПрдЧрд╛, рдФрд░ рдЦреЛрдЬ рдХреЗ рд▓рд┐рдП рдирдИ рджрд┐рд╢рд╛ рдирд╣реАрдВред
// Add the simplex and determine a new direction simplex.Add(supportPoint); direction = simplex.CalculateDirection();
- рддреНрд░рд┐рдХреЛрдг рдХреЗ рд╕рд┐рдВрдкреНрд▓реЗрдХреНрд╕ рдХреЗ рдмрд┐рдВрджреБрдУрдВ рдХреЛ рд▓реЗрдВред
a: (-2,-2)
b: (0,-3)
c: (0,2)
ao: (2,2)
// Get a, the last point added to the simplex const a = this.points[this.points.length - 1]; // Since a was just added, we know that the inverse of a points // towards the origin const ao = a.Invert(); // If the simplex is a triangle if (this.points.length == 3) { // B is the penultimate in the simplex // C is the oldest point in the simplex const b = this.points[1]; const c = this.points[0];
- рд╕реЗрдЧрдореЗрдВрдЯ ab рдФрд░ ac рд▓реЗрдВред
ab: (2,-1)
рдПрд╕реА: (2,4)
// Determine a->b and a->c lines const ab = b.Sub(a); const ac = c.Sub(a);
- рд╣рдо рд╕рд┐рдореНрдкрд▓реЗрдХреНрд╕ рд╕реЗ рдирд┐рд░реНрджреЗрд╢рд┐рдд рд╕реЗрдЧрдореЗрдВрдЯ рдПрдм рдХреЗ рд▓рд┐рдП рд▓рдВрдмрд╡рдд рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВред
abperp: (-1,-2)
// Determine perpendicular of the a->b line let abPerp = new Vector(ab.y, -ab.x); // Check the handedness of the perpendicular, it should // face AWAY from the simplex if (abPerp.Dot(c) >= 0) { abPerp = abPerp.Invert(); }
- рд╣рдо рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдореВрд▓ рдПрдмреАрд╕реА рд╕реЗ рдкрд░реЗ рд╕рд┐рдореНрдкреНрд▓реЗрдХреНрд╕ рдХреЗ рдмрд╛рд╣рд░ рд╣реИред
abPerp.Dot (ao): -6
рдЙрддреНрдкрддреНрддрд┐ рдПрдм рд╕реЗ рдкрд░реЗ рд╕рд┐рдореНрдкреНрд▓реЗрдХреНрд╕ рдХреЗ рдмрд╛рд╣рд░ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИред
if (abPerp.Dot(ao) > 0) { this.points.splice(0, 1); return abPerp; }
- рд╣рдо рд╕рд┐рдореНрдкреНрд▓реЗрдХреНрд╕ рд╕реЗ рдирд┐рд░реНрджреЗрд╢рд┐рдд рд╕реЗрдЧрдореЗрдВрдЯ рдХреЗ рд▓рд┐рдП рд▓рдВрдмрд╡рдд рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВред
acPerp: (-4,2)
// Determine perpendicular of the a->c line let acPerp = new Vector(ac.y, -ac.x); // Check the handedness of the perpendicular, it should // face AWAY from the simplex if (acPerp.Dot(b) >= 0) { acPerp = acPerp.Invert(); }
- рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдВ рдХрд┐ рдореВрд▓ рдПрд╕реА рд╕реЗ рдкрд░реЗ рд╕рд┐рдореНрдкреНрд▓реЗрдХреНрд╕ рдХреЗ рдмрд╛рд╣рд░ рд╣реИ рдпрд╛ рдирд╣реАрдВред
acPerp.Dot (ao): -4
рдореВрд▓ ab рдХреЗ рдкрд░реЗ рд╕рд┐рдВрдкреНрд▓реЗрдХреНрд╕ рдХреЗ рдмрд╛рд╣рд░ рдирд╣реАрдВ рд╣реИред
// If the origin lies outside of the simplex remove the // point and determine a new direction in the direction // of the perpendicular; aiming to try to encapsulate // the origin that lies outside if (acPerp.Dot(ao) > 0) { this.points.splice(1, 1); return acPerp; }
- рдЪреВрдБрдХрд┐ рдЗрд╕ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдореЗрдВ AB рдФрд░ AC рдХреА рдЬрд╛рдБрдЪ рдХреА рдЧрдИ рдереА, рдФрд░ рд╣рдо рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ BC рдХреА рдкрд┐рдЫрд▓реА рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдореЗрдВ рдЬрд╛рдБрдЪ рдХреА рдЧрдИ рдереА, рдореВрд▓ рдХреЛ рд╕рд┐рдореНрдкреНрд▓реЗрдХреНрд╕ рдХреЗ рдЕрдВрджрд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдЗрд╕рд▓рд┐рдП рдПрдХ рдЯрдХреНрдХрд░ / рдЪреМрд░рд╛рд╣реЗ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдпрд╛ рдЧрдпрд╛ рдерд╛ - рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рд╕реВрдЪрд┐рдд рдХрд░рддреЗ рд╣реБрдП, рдлрд╝рдВрдХреНрд╢рди
undefined
рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рдПрдЧрд╛ред
- рдЪреВрдВрдХрд┐ рдПрдХ рдЯрдХрд░рд╛рд╡ рдХрд╛ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ, рд▓реВрдк рдмрд╛рд╣рд░ рдирд┐рдХрд▓ рдЧрдпрд╛ рд╣реИ рдФрд░ рджреЛ рдЖрдВрдХрдбрд╝реЛрдВ рдХреЗ рдмреАрдЪ рдЯрдХрд░рд╛рд╡ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ
Collision
рдЬрд╛рдирдХрд╛рд░реА рд╡рд╛рдкрд╕ рдЖ рдЧрдИ рд╣реИред
direction = simplex.CalculateDirection(); } // No direction calculated, intersection detected return new Collision(a, b);
рдирд┐рд╖реНрдХрд░реНрд╖
рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрд╣ рд▓реЗрдЦ рдЖрдкрдХреЛ GJK рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХреЛ рд╕рдордЭрдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдЧрд╛ред рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рджреЛ рдЖрдВрдХрдбрд╝реЛрдВ рдХреЗ рдмреАрдЪ рд╕рдВрдШрд░реНрд╖ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣рд╛рдВ / рдирд╣реАрдВ рдореЗрдВ рдЬрд╡рд╛рдм рджреЗрддрд╛ рд╣реИред рдмрд╣реБрднреБрдЬ рдФрд░ рд╕рд░реНрдХрд▓ рдХреЗ рд╕рд╛рде рдПрдХ рдХрд╛рдо рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдЙрджрд╛рд╣рд░рдг
рдЗрд╕ рдкрдж рдХреЗ рд▓рд┐рдП рднрдВрдбрд╛рд░ рдореЗрдВ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЖрдк рджреЛ рдЖрдВрдХрдбрд╝реЗ, рдЯрдХрд░рд╛рд╡ рд╕рд╛рдорд╛рдиреНрдп, рдФрд░ рд╕рдВрдкрд░реНрдХ рдмрд┐рдВрджреБ рдХреЗ рдмреАрдЪ рдкреНрд░рд╡реЗрд╢ рджреВрд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдФрд░ рддрдХрдиреАрдХреЛрдВ рдХреЗ рд╕рд╛рде рдЗрд╕ рдХреЛрдб рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
Dyn4j рдкреЛрд╕реНрдЯ рдХреЗ рд╡рд┐рднрд┐рдиреНрди рдЯрдХрд░рд╛рд╡ / рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдорд╛рдиреНрдпрддрд╛ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдкрд░ рдЕрдЪреНрдЫреЗ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЗ рд▓рд┐рдВрдХ рд╣реИрдВ; рдпрджрд┐ рдЖрдк рдЬреАрдЬреЗрдХреЗ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдЙрдирдХрд╛ рдЕрдзреНрдпрдпрди рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред