PAAvoid Struct Reference

#include <actions.h>

Inheritance diagram for PAAvoid:

Inheritance graph
[legend]
Collaboration diagram for PAAvoid:

Collaboration graph
[legend]

List of all members.

Public Member Functions

 ~PAAvoid ()
void Exec (const PDTriangle &dom, ParticleGroup &group, ParticleList::iterator ibegin, ParticleList::iterator iend)
void Exec (const PDRectangle &dom, ParticleGroup &group, ParticleList::iterator ibegin, ParticleList::iterator iend)
void Exec (const PDPlane &dom, ParticleGroup &group, ParticleList::iterator ibegin, ParticleList::iterator iend)
void Exec (const PDSphere &dom, ParticleGroup &group, ParticleList::iterator ibegin, ParticleList::iterator iend)
void Exec (const PDDisc &dom, ParticleGroup &group, ParticleList::iterator ibegin, ParticleList::iterator iend)

Public Attributes

pDomainposition
float look_ahead
float magnitude
float epsilon
 EXEC_METHOD


Detailed Description

Definition at line 45 of file actions.h.


Constructor & Destructor Documentation

PAAvoid::~PAAvoid (  )  [inline]

Definition at line 54 of file actions.h.

References position.

00054 {delete position;}


Member Function Documentation

void PAAvoid::Exec ( const PDTriangle dom,
ParticleGroup group,
ParticleList::iterator  ibegin,
ParticleList::iterator  iend 
)

Definition at line 31 of file actions.cpp.

References PDTriangle::D, PActionBase::dt, epsilon, fsqr(), pVec::length(), pVec::length2(), look_ahead, magnitude, NewBasis(), pVec::normalize(), PDTriangle::nrm, PDTriangle::p, Particle::pos, pSameSign(), PDTriangle::u, PDTriangle::uNrm, PDTriangle::v, Particle::vel, and PDTriangle::vNrm.

00032 {
00033     float magdt = magnitude * dt;
00034 
00035     const pVec &u = dom.u;
00036     const pVec &v = dom.v;
00037 
00038     // The normalized bases are needed inside the loop.
00039     const pVec &un = dom.uNrm;
00040     const pVec &vn = dom.vNrm;
00041 
00042     // f is the third (non-basis) triangle edge.
00043     pVec f = v - u;
00044     pVec fn = f;
00045     fn.normalize();
00046 
00047     // Compute the inverse matrix of the plane basis.
00048     pVec s1, s2;
00049     NewBasis(u, v, s1, s2);
00050 
00051     for (ParticleList::iterator it = ibegin; it != iend; it++) {
00052         Particle &m = (*it);
00053 
00054         // See if particle's current and look_ahead positions cross plane.
00055         // If not, couldn't hit, so keep going.
00056         pVec pnext = m.pos + m.vel * dt * look_ahead;
00057 
00058         // nrm stores the plane normal (the a,b,c of the plane eqn).
00059         // Old and new distances: dist(p,plane) = n * p + d
00060         float distold = m.pos * dom.nrm + dom.D;
00061         float distnew = pnext * dom.nrm + dom.D;
00062 
00063         if(pSameSign(distold, distnew))
00064             continue;
00065 
00066         float nv = dom.nrm * m.vel;
00067         float t = -distold / nv; // Time steps before hit
00068 
00069         pVec phit = m.pos + m.vel * t; // Actual intersection point
00070         pVec offset = phit - dom.p; // Offset from origin in plane
00071 
00072         // Dot product with basis vectors of old frame
00073         // in terms of new frame gives position in uv frame.
00074         float upos = offset * s1;
00075         float vpos = offset * s2;
00076 
00077         // Did it cross plane outside triangle?
00078         if(upos < 0 || vpos < 0 || (upos + vpos) > 1)
00079             continue;
00080 
00081         // A hit! A most palpable hit!
00082         // Compute distance to the three edges.
00083         pVec uofs = (un * (un * offset)) - offset;
00084         float udistSqr = uofs.length2();
00085         pVec vofs = (vn * (vn * offset)) - offset;
00086         float vdistSqr = vofs.length2();
00087 
00088         pVec foffset = offset - u;
00089         pVec fofs = (fn * (fn * foffset)) - foffset;
00090         float fdistSqr = fofs.length2();
00091 
00092         // S is the safety vector toward the closest point on boundary.
00093         pVec S;
00094         if(udistSqr <= vdistSqr && udistSqr <= fdistSqr) S = uofs;
00095         else if(vdistSqr <= fdistSqr) S = vofs;
00096         else S = fofs;
00097 
00098         // Blend S with m.vel.
00099         S.normalize();
00100 
00101         float vm = m.vel.length();
00102         pVec Vn = m.vel / vm;
00103 
00104         pVec dir = (S * (magdt / (fsqr(t)+epsilon))) + Vn;
00105         m.vel = dir * (vm / dir.length()); // Speed of m.vel, but in direction dir.
00106     }
00107 }

Here is the call graph for this function:

void PAAvoid::Exec ( const PDRectangle dom,
ParticleGroup group,
ParticleList::iterator  ibegin,
ParticleList::iterator  iend 
)

Definition at line 109 of file actions.cpp.

References PDRectangle::D, PActionBase::dt, epsilon, fsqr(), pVec::length(), pVec::length2(), look_ahead, magnitude, NewBasis(), pVec::normalize(), PDRectangle::nrm, PDRectangle::p, Particle::pos, pSameSign(), PDRectangle::u, PDRectangle::uNrm, PDRectangle::v, Particle::vel, and PDRectangle::vNrm.

00110 {
00111     float magdt = magnitude * dt;
00112 
00113     const pVec &u = dom.u;
00114     const pVec &v = dom.v;
00115 
00116     // The normalized bases are needed inside the loop.
00117     const pVec &un = dom.uNrm;
00118     const pVec &vn = dom.vNrm;
00119 
00120     // Compute the inverse matrix of the plane basis.
00121     pVec s1, s2;
00122     NewBasis(u, v, s1, s2);
00123 
00124     for (ParticleList::iterator it = ibegin; it != iend; it++) {
00125         Particle &m = (*it);
00126 
00127         // See if particle's current and look_ahead positions cross plane.
00128         // If not, couldn't hit, so keep going.
00129         pVec pnext = m.pos + m.vel * dt * look_ahead;
00130 
00131         // nrm stores the plane normal (the a,b,c of the plane eqn).
00132         // Old and new distances: dist(p,plane) = n * p + d
00133         float distold = m.pos * dom.nrm + dom.D;
00134         float distnew = pnext * dom.nrm + dom.D;
00135 
00136         if(pSameSign(distold, distnew))
00137             continue;
00138 
00139         float nv = dom.nrm * m.vel;
00140         float t = -distold / nv;
00141 
00142         pVec phit = m.pos + m.vel * t; // Actual intersection point
00143         pVec offset = phit - dom.p; // Offset from origin in plane
00144 
00145         // Dot product with basis vectors of old frame
00146         // in terms of new frame gives position in uv frame.
00147         float upos = offset * s1;
00148         float vpos = offset * s2;
00149 
00150         // Did it cross plane outside rectangle?
00151         if(upos < 0 || vpos < 0 || upos > 1 || vpos > 1)
00152             continue;
00153 
00154         // A hit! A most palpable hit!
00155         // Compute distance to the three edges.
00156         pVec uofs = (un * (un * offset)) - offset;
00157         float udistSqr = uofs.length2();
00158         pVec vofs = (vn * (vn * offset)) - offset;
00159         float vdistSqr = vofs.length2();
00160 
00161         pVec foffset = (u + v) - offset;
00162         pVec fofs = (un * (un * foffset)) - foffset;
00163         float fdistSqr = fofs.length2();
00164         pVec gofs = (un * (un * foffset)) - foffset;
00165         float gdistSqr = gofs.length2();
00166 
00167         pVec S;
00168         if(udistSqr <= vdistSqr && udistSqr <= fdistSqr
00169                 && udistSqr <= gdistSqr) S = uofs;
00170         else if(vdistSqr <= fdistSqr && vdistSqr <= gdistSqr) S = vofs;
00171         else if(fdistSqr <= gdistSqr) S = fofs;
00172         else S = gofs;
00173 
00174         // Blend S with m.vel.
00175         S.normalize();
00176 
00177         float vm = m.vel.length();
00178         pVec Vn = m.vel / vm;
00179 
00180         pVec dir = (S * (magdt / (fsqr(t)+epsilon))) + Vn;
00181         m.vel = dir * (vm / dir.length()); // Speed of m.vel, but in direction dir.
00182     }
00183 }

Here is the call graph for this function:

void PAAvoid::Exec ( const PDPlane dom,
ParticleGroup group,
ParticleList::iterator  ibegin,
ParticleList::iterator  iend 
)

Definition at line 185 of file actions.cpp.

References PDPlane::D, PActionBase::dt, epsilon, fsqr(), pVec::length(), look_ahead, magnitude, PDPlane::nrm, Particle::pos, pSameSign(), and Particle::vel.

00186 {
00187     float magdt = magnitude * dt;
00188 
00189     for (ParticleList::iterator it = ibegin; it != iend; it++) {
00190         Particle &m = (*it);
00191 
00192         // See if particle's current and look_ahead positions cross plane.
00193         // If not, couldn't hit, so keep going.
00194         pVec pnext = m.pos + m.vel * dt * look_ahead;
00195 
00196         // nrm stores the plane normal (the a,b,c of the plane eqn).
00197         // Old and new distances: dist(p,plane) = n * p + d
00198         float distold = m.pos * dom.nrm + dom.D;
00199         float distnew = pnext * dom.nrm + dom.D;
00200 
00201         if(pSameSign(distold, distnew))
00202             continue;
00203 
00204         float nv = dom.nrm * m.vel;
00205         float t = -distold / nv;
00206 
00207         // Blend S with m.vel.
00208         const pVec &S = dom.nrm;
00209 
00210         float vm = m.vel.length();
00211         pVec Vn = m.vel / vm;
00212 
00213         pVec dir = (S * (magdt / (fsqr(t)+epsilon))) + Vn;
00214         m.vel = dir * (vm / dir.length()); // Speed of m.vel, but in direction dir.
00215     }
00216 }

Here is the call graph for this function:

void PAAvoid::Exec ( const PDSphere dom,
ParticleGroup group,
ParticleList::iterator  ibegin,
ParticleList::iterator  iend 
)

Definition at line 219 of file actions.cpp.

References PDSphere::ctr, PActionBase::dt, epsilon, fsqr(), pVec::length(), look_ahead, magnitude, pVec::normalize(), Particle::pos, PDSphere::radOutSqr, sqrtf(), and Particle::vel.

00220 {
00221     float magdt = magnitude * dt;
00222 
00223     for (ParticleList::iterator it = ibegin; it != iend; it++) {
00224         Particle &m = (*it);
00225 
00226         // First do a ray-sphere intersection test and see if it's soon enough.
00227         // Can I do this faster without t?
00228         float vm = m.vel.length();
00229         pVec Vn = m.vel / vm;
00230 
00231         pVec L = dom.ctr - m.pos;
00232         float v = L * Vn;
00233 
00234         float disc = dom.radOutSqr - (L * L) + fsqr(v);
00235         if(disc < 0)
00236             continue; // I'm not heading toward it.
00237 
00238         // Compute length for second rejection test.
00239         float t = v - sqrtf(disc);
00240         if(t < 0 || t > (vm * look_ahead))
00241             continue;
00242 
00243         // Get a vector to safety.
00244         pVec C = Cross(Vn, L);
00245         C.normalize();
00246         pVec S = Cross(Vn, C);
00247 
00248         pVec dir = (S * (magdt / (fsqr(t)+epsilon))) + Vn;
00249         m.vel = dir * (vm / dir.length()); // Speed of m.vel, but in direction dir.
00250     }
00251 }

Here is the call graph for this function:

void PAAvoid::Exec ( const PDDisc dom,
ParticleGroup group,
ParticleList::iterator  ibegin,
ParticleList::iterator  iend 
)

Definition at line 253 of file actions.cpp.

References PDDisc::D, PActionBase::dt, epsilon, fsqr(), pVec::length(), pVec::length2(), look_ahead, magnitude, PDDisc::nrm, PDDisc::p, Particle::pos, pSameSign(), PDDisc::radOutSqr, and Particle::vel.

00254 {
00255     float magdt = magnitude * dt;
00256 
00257     for (ParticleList::iterator it = ibegin; it != iend; it++) {
00258         Particle &m = (*it);
00259 
00260         // See if particle's current and look_ahead positions cross plane.
00261         // If not, couldn't hit, so keep going.
00262         pVec pnext = m.pos + m.vel * dt * look_ahead;
00263 
00264         // nrm stores the plane normal (the a,b,c of the plane eqn).
00265         // Old and new distances: dist(p,plane) = n * p + d
00266         float distold = m.pos * dom.nrm + dom.D;
00267         float distnew = pnext * dom.nrm + dom.D;
00268 
00269         if(pSameSign(distold, distnew))
00270             continue;
00271 
00272         float nv = dom.nrm * m.vel;
00273         float t = -distold / nv;
00274 
00275         pVec phit = m.pos + m.vel * t; // Actual intersection point
00276         pVec offset = phit - dom.p; // Offset from origin in plane
00277 
00278         float radSqr = offset.length2();
00279 
00280         // Are we going to hit the disc ring? If so, always turn to the OUTSIDE of the ring.
00281         if(radSqr < dom.radInSqr || radSqr > dom.radOutSqr)
00282             continue;
00283 
00284         // Blend S with m.vel.
00285         pVec S = offset;
00286 
00287         float vm = m.vel.length();
00288         pVec Vn = m.vel / vm;
00289 
00290         pVec dir = (S * (magdt / (fsqr(t)+epsilon))) + Vn;
00291         m.vel = dir * (vm / dir.length()); // Speed of m.vel, but in direction dir.
00292     }
00293 }

Here is the call graph for this function:


Member Data Documentation

pDomain* PAAvoid::position

Definition at line 47 of file actions.h.

Referenced by pAvoid(), and ~PAAvoid().

float PAAvoid::look_ahead

Definition at line 48 of file actions.h.

Referenced by Exec(), and pAvoid().

float PAAvoid::magnitude

Definition at line 49 of file actions.h.

Referenced by Exec(), and pAvoid().

float PAAvoid::epsilon

Definition at line 50 of file actions.h.

Referenced by Exec(), and pAvoid().

PAAvoid::EXEC_METHOD

Reimplemented from PActionBase.

Definition at line 52 of file actions.h.


The documentation for this struct was generated from the following files:
Generated on Sat Mar 15 23:51:09 2008 for Armagetron Advanced by  doxygen 1.5.4