3D Tifin umbberez

Amagrad agi yettakked tazwart i yal itiknikiyen n wablaɣ n ujemmeq yettwasqedcen iw sedday n tifin umbberez deg tiwenaḍin 3D.imagraden n uḍfaṛ i tuddela usedday deg timkkarḍitin tulmisin 3D.

Tankult n ujemmeq usemsawi ɣef tinakatin

Am tifin umbberez 2D,tinakatin ujemmeq asemsawi n ugellus (TJSG) d iwarzimen izerben iw guccel n sin agi  ifendasen n wurar ma yella sembebbin naɣ ahu.ayagi iw sburu ifendasen n wurar deg yiwet n tanaka ur nezzi.(akka tesemsawi s agellus) u ateselken ideggan n tixxamin deg tallunt n imsidag 3D akken anẓaṛ ma yella temsembeddint.

Tugdda yemsemsawin ɣef tanaka tella iw akken ad illint timellal.asembebbi ger snat n tinakatin ur nezzi nezmer ad ttwadaddent s isnemhal timeẓliwin daya,maca tinakatin yezzin yesefk-asent timehlin timastayin,ig ẓayen iw siḍen.ma ɣuṛwen ifendasen ara yezzin,tzemrem attbeddelem iseggiwen n taɣzut n talast iw akken ed yesegrer yal-ass taɣawsa,naɣ mulac ad yilli ufran nniḍen n tanzeggit n talast,am tabluleɣt (yellan ttimsaritin i tuzzya).yeskanay-ed amedya n tuzzya n  (TJSG) ig smezgay afendas yettezzin,tanaka tettbeddil yal ass tisektiwin iw akken att smezgay akken iwata ɣer tanaka yellan degs..

Tamawt: Walit amagrad Bounding Iblaɣen akked Three.js iw akken ateẓṛem asnulfu yellan tallilt n tatiknikit agi.

Ired mgal TJSG

Sefqed  ired ma yella deg gensu n TJSG (AABB) ayagi d afrari - neḥwaǧ kkan a nefrari  imsidgen n ired yellan deg gensu n TJSG (AABB);get yal agellus s ubrez.anɣil belli Px, Py ed Pz d imsigen n ired  BminX-BmaxX,BminY-BmaxY ed BminZ-BmaxZ nutenti id tagrummiwin n yal exist n TJSG (AABB),nezmer a nesḍen ma yeḍṛad umbberez ger sin agi s useqdec n tasemselt agi:

f(P,B)=(Px>=BaddXPx<=BafelX)(Py>=BaddYPy<=BafelY)(Pz>=BaddZPz<=BafelZ)f(P,B)= (P_x >= B_{minX} \wedge P_x <= B_{maxX}) \wedge (P_y >= B_{minY} \wedge P_y <= B_{maxY}) \wedge (P_z >= B_{minZ} \wedge P_z <= B_{maxZ})

Anda deg JavaScript:

Tasɣent d ired deg gensu n TJSB AABB(ired, tanaka) {
 Tuɣalin(ired.x >= tanaka.addayX && ired.x <= tanaka.afellayX) &&
         (ired.y >= tanaka.addayY && ired.y <= tanaka.afellayY) &&
         (ired.z >= tanaka.addayY && ired.z <= tanaka.afellayZ);


Sefqed ma yella AABB imyagger AABB nniḍen deg ukayad n ired.Neḥwaǧ kkan aneg akayad i yal agellas , s useqdec n ibuda n tinakatin.ameskan agi sedawa yeskanay-ed akayad i nesedday ɣef ugellus n X-adasil,tiseddaṛin AddayXAfellayX ed BddayXBfellayX  semnenint?

updated version

S tusnakt atan d'acu ara d yefɣen:

f(A,B)=(<=BfellayXAfellayX>=BddayX)(AddayY<=BfellayYAfellayY>=BddayY)(AddayZ<=BfellayZAfellayZ>=BfellayZ)f(A,B) =

u deg JavaScript a neseqdec aya:

   Tiseɣnatin myaggerent(a, b) {
   tuɣalin (a.ddayX <= b.fellayX && a.fellayX >= b.ddayX) &&
         (a.ddayY <= b.fellayY && a.fellayY >= b.ddayY) &&
         (a.ddayZ <= b.fellayZ && a.fellayZ >= b.ddayZ); 

Bounding spheres

Using bounding spheres to detect collisions is a bit more complex than AABB, but still fairly quick to test. The main advantage of spheres is that they are invariant to rotation, so if the wrapped entity rotates, the bounding sphere would still be the same. Their main disadvantage is that unless the entity they are wrapping is actually spherical, the wrapping is usually not a good fit (i.e. wrapping a person with a bounding sphere will cause a lot of false positives, whereas a AABB would be a better match).

Point versus sphere

To check whether an sphere contains a point we need to calculate the distance between the point and the sphere's center. If this distance is smaller than or equal to the radius of the sphere, the point is inside it.

Taking into account that the euclidean distance between two points A and B is (Ax-Bx)2)+(Ay-By)2+(Az-Bz)\sqrt{(A_x - B_x) ^ 2) + (A_y - B_y)^2 + (A_z - B_z)} , our formula for point versus sphere collision detection would work out like so:

f(P,S)=Sradius>=(Px-Sx)2+(Py-Sy)2+(Pz-Sz)2f(P,S) = S_{radius} >= \sqrt{(P_x - S_x)^2 + (P_y - S_y)^2 + (P_z - S_z)^2}

Or in JavaScript:

function isPointInsideSphere(point, sphere) {
  // we are using multiplications because is faster than calling Math.pow
  var distance = Math.sqrt((point.x - sphere.x) * (point.x - sphere.x) +
                           (point.y - sphere.y) * (point.y - sphere.y) +
                           (point.z - sphere.z) * (point.z - sphere.z));
  return distance < sphere.radius;

The code above features a square root, which can be expensive to calculate. An easy optimization to avoid it consists of squaring the radius, so the optimized equation would instead involve distance < sphere.radius * sphere.radius.

Sphere versus sphere

The sphere vs sphere test is similar to the point vs sphere test. What we need to test here is that the distance between the sphere's centers is less than or equal to the sum of their radii.

Mathematically, this looks like so:

f(A,B)=(Ax-Bx)2+(Ay-By)2+(Az-Bz)2<=Aradius+Bradiusf(A,B) = \sqrt{(A_x - B_x)^2 + (A_y - B_y)^2 + (A_z - B_z)^2} <= A_{radius} + B_{radius}

Or in JavaScript:

function intersect(sphere, other) {
  // we are using multiplications because it's faster than calling Math.pow
  var distance = Math.sqrt((sphere.x - other.x) * (sphere.x - other.x) +
                           (sphere.y - other.y) * (sphere.y - other.y) +
                           (sphere.z - other.z) * (sphere.z - other.z));
  return distance < (sphere.radius + other.radius); }

Sphere versus AABB

Testing whether a sphere and an AABB are colliding is slightly more complicated, but still simple and fast. A logical approach would be to check every vertex of the AABB, doing a point vs sphere test for each one. This is overkill however — testing all the vertices is unnecessary, as we can get away with just calculating the distance between the AABB's closest point (not necessarily a vertex) and the sphere's center, seeing if it is less than or equal to the sphere's radius. We can get this value by clamping the sphere's center to the AABB's limits.

In JavaScript, we'd do this test like so:

function intersect(sphere, box) {
  // get box closest point to sphere center by clamping
  var x = Math.max(box.minX, Math.min(sphere.x, box.maxX);
  var y = Math.max(box.minY, Math.min(sphere.y, box.maxY);
  var z = Math.max(box.minZ, Math.min(sphere.z, box.maxZ);

  // this is the same as isPointInsideSphere
  var distance = Math.sqrt((x - sphere.x) * (x - sphere.x) +
                           (y - sphere.y) * (y - sphere.y) +
                           (z - sphere.z) * (z - sphere.z));
  return distance < sphere.radius;

Using a physics engine

3D physics engines provide collision detection algorithms, most of them based on bounding volumes as well. The way a physics engine works is by creating a physical body, usually attached to a visual representation of it. This body has properties such as velocity, position, rotation, torque, etc., and also a physical shape. This shape is the one that is considered in the collision detection calculations.

We have prepared a live collision detection demo (with source code) that you can take a look at to see such techniques in action — this uses the open-source 3D physics engine cannon.js.

See also

Related articles on MDN:

External resources: