Rhino C++ API
8.13
|
#include <opennurbs_plus_particle.h>
Classes | |
class | ON_Force |
class | ON_IntegrateContext |
class | ON_Particle |
class | ON_ParticleIterator |
class | ON_ParticleState |
Public Member Functions | |
ON_ParticleSystem () | |
bool | AccumulateForces () |
class ON_ParticleSystem::ON_Particle * | AddFixedParticle (double mass, ON_3dPoint initial_position) |
class ON_ParticleSystem::ON_Force * | AddHooksSpringForce (class ON_ParticleSystem::ON_Particle *particle1, class ON_ParticleSystem::ON_Particle *particle2, double rest_length, double spring_constant, double damping_constant) |
class ON_ParticleSystem::ON_Force * | AddInverseDistanceSquaredForce (class ON_ParticleSystem::ON_Particle *particle1, class ON_ParticleSystem::ON_Particle *particle2, double c, double minimum_distance) |
class ON_ParticleSystem::ON_Force * | AddNaryForce (bool(*force_function)(ON__UINT_PTR, class ON_ParticleSystem::ON_Particle **), ON__UINT_PTR context, unsigned int particle_count, class ON_Particle **particles) |
class ON_ParticleSystem::ON_Particle * | AddParticle (double mass, ON_3dPoint initial_position) |
class ON_ParticleSystem::ON_Particle * | AddParticle (double mass, ON_3dPoint initial_position, ON_3dVector initial_velocity) |
class ON_ParticleSystem::ON_Particle * | AddParticle (double mass, ON_3dPoint initial_position, ON_3dVector initial_velocity, ON_3dVector initial_acceleration) |
class ON_ParticleSystem::ON_Force * | AddUnaryForce (bool(*force_function)(ON__UINT_PTR, class ON_ParticleSystem::ON_Particle *), ON__UINT_PTR context) |
ON_BoundingBox | BoundingBox () const |
double | CurrentTime () const |
double | GlobalDragForceCoefficient (int i) const |
ON_3dVector | GlobalGravityForce () const |
bool | IncrementTime (bool(*integrate_func)(class ON_ParticleSystem::ON_IntegrateContext &), ON__UINT_PTR integrate_context, double delta_time) |
bool | IncrementTimeEuler (double delta_time) |
bool | IncrementTimeSemiImplicitEuler (bool(*integrate_func)(class ON_ParticleSystem::ON_IntegrateContext &), ON__UINT_PTR integrate_context, double delta_time) |
bool | IncrementTimeVelocityVeret (bool(*integrate_func)(class ON_ParticleSystem::ON_IntegrateContext &), ON__UINT_PTR integrate_context, double delta_time) |
bool | IncrementTimeVerlet (bool(*integrate_func)(class ON_ParticleSystem::ON_IntegrateContext &), ON__UINT_PTR integrate_context, double delta_time) |
const class ON_ParticleSystem::ON_Particle * | MaximumIncrementalChange () const |
double | PreviousTime () const |
void | SetGlobalDragForce (double drag_coefficient1, double drag_coefficient2, double drag_coefficient3) |
void | SetGlobalGravityForce (ON_3dVector G) |
bool | SetStartTime (double start_time) |
Static Public Member Functions | |
static bool | IntegrateEuler (class ON_ParticleSystem::ON_IntegrateContext &context) |
static bool | IntegrateSemiImplicitEuler (class ON_ParticleSystem::ON_IntegrateContext &context) |
static bool | IntegrateVelocityVerlet1 (class ON_ParticleSystem::ON_IntegrateContext &context) |
static bool | IntegrateVerlet (class ON_ParticleSystem::ON_IntegrateContext &context) |
ON_ParticleSystem::ON_ParticleSystem | ( | ) |
bool ON_ParticleSystem::AccumulateForces | ( | ) |
class ON_ParticleSystem::ON_Particle* ON_ParticleSystem::AddFixedParticle | ( | double | mass, |
ON_3dPoint | initial_position | ||
) |
class ON_ParticleSystem::ON_Force* ON_ParticleSystem::AddHooksSpringForce | ( | class ON_ParticleSystem::ON_Particle * | particle1, |
class ON_ParticleSystem::ON_Particle * | particle2, | ||
double | rest_length, | ||
double | spring_constant, | ||
double | damping_constant | ||
) |
Description: Adds a Hook's law spring force between particles that is proportional to (distance - rest_length). Parameters: particle1 - [in] particle2 - [in] rest_length - [in] rest length of the spring. spring_constant - [in] Spring force magnitude = spring_constant*(distance - rest_length). When spring_constant > 0 and distance > rest_length, the force attracts. damping_constant - [in] Damping force magnitude = damping_constant*|(delta velocity) o D|, where D is a unit vector points from one particle to the other. When damping_constant > 0 and the particles are moving towards each other, the damping force repels. When damping_constant > 0 and the particles are moving away from each other, the damping force attracts.
class ON_ParticleSystem::ON_Force* ON_ParticleSystem::AddInverseDistanceSquaredForce | ( | class ON_ParticleSystem::ON_Particle * | particle1, |
class ON_ParticleSystem::ON_Particle * | particle2, | ||
double | c, | ||
double | minimum_distance | ||
) |
Description: Adds binary force between particles that is proportional to 1/(distance squared). Parameters: particle1 - [in] particle2 - [in] c - [in] force = c/d^2 c > 0 for attractive forces c < 0 for repulsive forces minimum_distance - [in] If the distance between the particles is < minimum_distance, then the force evaluator fails. Example: Gravity: double g = 6.672e-11; ///< N m^2/kg^2 double c = g*mass1*mass2; double min_distance = (radius1+radius2); AddInverseDistanceSquaredForce(p1,p2,c,min_distance); Coulumb's Force double k = 8.9875e9; ///< N m^2/C^2 double c = -k*charge1*charge2; double min_distance = (radius1+radius2); AddInverseDistanceSquaredForce(p1,p2,c,min_distance);
class ON_ParticleSystem::ON_Force* ON_ParticleSystem::AddNaryForce | ( | bool(*)(ON__UINT_PTR, class ON_ParticleSystem::ON_Particle **) | force_function, |
ON__UINT_PTR | context, | ||
unsigned int | particle_count, | ||
class ON_Particle ** | particles | ||
) |
Description: A N-ary force acts on a fixed set of particles.
Parameters: force_function - [in] A function that calculates the force on the particles listed in the particles[] array parameter. If force_function() returns false, the solver will stop.
context - [in] First parameter passed to force_function.
If the information in your context consists of up to 4 doubles, then you may use the ON_Force.m_context member as shown in the example.
particle_count - [in] Number of particles in particles[] array.
particles[] - [in] List of particles this force acts on.
Example: / Hook's law spring / This example if for illustration purposes. / In practice it is more efficient to call ON_ParticleSystem::AddHooksSpringForce().
struct HooksSpringForceContext { double m_rest_length; double m_spring_constant; double m_damping_constant; }; static bool HooksSpringForceFunction( ON__UINT_PTR context, class ON_ParticleSystem::ON_Particle** particles ) { const ON_3dVector dx = particles[1]->m_position - particles[0]->m_position; const double length = dx.Length(); if ( length > 0.0 ) { const ON_3dVector dv = particles[1]->m_velocity - particles[0]->m_velocity; const struct HooksSpringForceContext* spring_context = (const struct HooksSpringForceContext*)context; double f = spring_context->m_spring_constant*(1.0 - spring_context->m_rest_length/length) + spring_context->m_damping_constant*((dv.x*dx.x + dv.y*dx.y + dv.z*dx.z)/(length*length)); ON_3dVector F = f*dx; particles[0]->m_force += F; particles[1]->m_force -= F; } return true; } class ON_ParticleSystem::ON_Particle* particle1 = ...; class ON_ParticleSystem::ON_Particle* particle2 = ...; double rest_length = ...; double spring_constant = ...; double damping_constant = ...; ON_ParticleSystem::ON_Particle* particles[2] = {particle1,particle2}; ON_Force* F = AddNaryForce(HooksSpringForceFunction,0,2,particles); if ( 0 != F ) { F->m_context.m_ptr = (ON__UINT_PTR)(&F->m_context.m_x[0]); struct HooksSpringForceContext* spring_context = (struct HooksSpringForceContext* )F->m_context.m_ptr; spring_context->m_rest_length = rest_length; spring_context->m_spring_constant = spring_constant; spring_context->m_damping_constant = damping_constant; }
Remarks: To add the common damped spring force that is calculated using Hook's law, it is easier to call AddHooksSpringForce().
class ON_ParticleSystem::ON_Particle* ON_ParticleSystem::AddParticle | ( | double | mass, |
ON_3dPoint | initial_position | ||
) |
Description: Add a particle to the system. Parameters: mass - [in] initial_position - [in] initial_velocity - [in] You may pass zero if you are using an integrator that does not need this value. initial_acceleration - [in] You may pass zero if you are using an integrator that does not need this value. Remarks: The constructors that omit initial_velocity or initial_acceleration assume those values are zero
class ON_ParticleSystem::ON_Particle* ON_ParticleSystem::AddParticle | ( | double | mass, |
ON_3dPoint | initial_position, | ||
ON_3dVector | initial_velocity | ||
) |
class ON_ParticleSystem::ON_Particle* ON_ParticleSystem::AddParticle | ( | double | mass, |
ON_3dPoint | initial_position, | ||
ON_3dVector | initial_velocity, | ||
ON_3dVector | initial_acceleration | ||
) |
class ON_ParticleSystem::ON_Force* ON_ParticleSystem::AddUnaryForce | ( | bool(*)(ON__UINT_PTR, class ON_ParticleSystem::ON_Particle *) | force_function, |
ON__UINT_PTR | context | ||
) |
Description: A unary force acts on every particle in the system.
Parameters: context - [in] First parameter passed to force_function.
force_function - [in] A function that calculates the force on the particle. If force_function() returns false, the solver will stop.
Example: If you had 8, or perhaps 9, particles representing the planets in our solar system, you were comfortable neglecting the effects the planets' mass have on the sun's position and you chose a coordinate system with the sun at the origin, then you could add a solar gravity force doing something like the following.
bool GetSolarGravity( void*, ///< no context required const class ON_ParticleSystem::ON_Particle* planet, ON_3dVector* SolarGravityForce ) {
/ masses in kilograms and distances in meters const double solar_mass = 1.9891e30; ///< kilograms const double g = 6.67384e-11; ///< meters^3/(kilogram seconds^2) ON_3dVector V = ON_3dPoint::Origin - planet->m_position; double r = V.Length();
if ( !(r > 6.955e8) ) { / Planet crashed into the sun! / The sun's radius is 6.955e8 meters. This calculation / ignores planets melting as they get too close to the sun. return false; } SolarGravityForce = (g*planet->m_mass*solar_mass/(r*r*r))*V; ///< r^3 because input V is not unitized return true; }
.... AddUnaryForce(0,GetSolarGravity);
Remarks: To add a global "gravity", it is more efficient to use SetGlobalGravityForce(). To add a global "drag" force, it is more efficient to use SetGlobalDragForce().
ON_BoundingBox ON_ParticleSystem::BoundingBox | ( | ) | const |
double ON_ParticleSystem::CurrentTime | ( | ) | const |
Returns: Current particle system time.
double ON_ParticleSystem::GlobalDragForceCoefficient | ( | int | i | ) | const |
ON_3dVector ON_ParticleSystem::GlobalGravityForce | ( | ) | const |
bool ON_ParticleSystem::IncrementTime | ( | bool(*)(class ON_ParticleSystem::ON_IntegrateContext &) | integrate_func, |
ON__UINT_PTR | integrate_context, | ||
double | delta_time | ||
) |
Description: Increment the current state of the particle system using a custom integration algorithm. Parameters: integrate_func - [in] An integration function.
You may use one of the canned methods listed below or provide your own. ON_ParticleSystem::IntegrateEuler() ON_ParticleSystem::IntegrateSemiImplicitEuler() ...
integrate_context - [in] value passed as context.m_integration_context. delta_time - [in] value passed as contextm_delta_time.
bool ON_ParticleSystem::IncrementTimeEuler | ( | double | delta_time | ) |
Description: Increment the current state of the particle system using the Euler integration algorithm. Parameters: delta_time - [in] Remarks: Calls IncrementTime with ON_ParticleSystem::IntegrateEuler as the integration function.
bool ON_ParticleSystem::IncrementTimeSemiImplicitEuler | ( | bool(*)(class ON_ParticleSystem::ON_IntegrateContext &) | integrate_func, |
ON__UINT_PTR | integrate_context, | ||
double | delta_time | ||
) |
Description: Increment the current state of the particle system using the semi-implicitly Euler integration algorithm. Parameters: delta_time - [in] Remarks: Calls IncrementTime with ON_ParticleSystem::IntegrateSemiImplicitEuler as the integration function.
bool ON_ParticleSystem::IncrementTimeVelocityVeret | ( | bool(*)(class ON_ParticleSystem::ON_IntegrateContext &) | integrate_func, |
ON__UINT_PTR | integrate_context, | ||
double | delta_time | ||
) |
Description: Increment the current state of the particle system using the velocity Verlet integration algorithm. Parameters: delta_time - [in] Remarks: Calls IncrementTime with ON_ParticleSystem::IntegrateVerlet as the integration function. Note that the Verlet algorithm does not calculate velocity values.
bool ON_ParticleSystem::IncrementTimeVerlet | ( | bool(*)(class ON_ParticleSystem::ON_IntegrateContext &) | integrate_func, |
ON__UINT_PTR | integrate_context, | ||
double | delta_time | ||
) |
Description: Increment the current state of the particle system using the Verlet integration algorithm. Parameters: delta_time - [in] Remarks: Calls IncrementTime with ON_ParticleSystem::IntegrateVerlet as the integration function. Note that the Verlet algorithm does not calculate velocity values.
|
static |
Description: Updates context.m_state.m_position and context.m_state.m_velocity using Euler integration.
Parameters: context - [in / out] The returned position and velocity are incremented using the following calculation. x1 = current position v1 = current velocity a1 = (current accumulated force)/(current mass) / incremented position and velocity x = x1 + v1*dt + 0.5*a1*dt*dt; v = v1 + a1*dt;
Remarks: This is the best choice in the rare case when all forces are independent of time. The canonical example when being when the only force is the force of gravity and no collisions occur. Note that forces whose formulae involve position or velocity are almost never independent of time. In particular, if your system has drag, damping or spring forces, then this is probably the worst choice for an integrator.
|
static |
Description: Updates context.m_state.m_position and context.m_state.m_velocity using Semi-implicit Euler integration.
Parameters: context - [in / out] The returned position and velocity are incremented using the following calculation. x1 = current position v1 = current velocity a1 = (current accumulated force)/(current mass) / incremented position and velocity v = v1 + a1*dt; x = x1 + v*dt + 0.5*a1*dt*dt;
|
static |
Description: Updates context.m_state.m_position and context.m_state.m_velocity using Stormer-Verlet integration.
Parameters: context - [in / out] The returned position is incremented using the following calculation. x1 = current position v1 = current velocity a1 = (current accumulated force)/(current mass) / incremented position v = v1 + 0.5* a1*dt; x = x1 + v*dt; Remarks: The velocity Verlet algorithm uses IntegrateVelocityVerlet1 as the first stemBecause the calculation requires a valid previous state, the initial iteration must be performed by another integrator. If context.m_particle->m_previous_state.m_time is ON_UNSET_VALUE, then IntegrateEuler is called.
|
static |
Description: Updates context.m_state.m_position using Verlet integration.
Parameters: context - [in / out] The returned position is incremented using the following calculation. x0 = previous position x1 = current position a1 = (current accumulated force)/(current mass) / incremented position x = 2*x1 - x0 + a1*dt*dt; Remarks:
const class ON_ParticleSystem::ON_Particle* ON_ParticleSystem::MaximumIncrementalChange | ( | ) | const |
Returns: A pointer to the particle that moved the farthest during the most recent call to IncrementTime(). This information is useful for adjusting time increments.
double ON_ParticleSystem::PreviousTime | ( | ) | const |
Returns: Particle system time at the previous iteration. ON_UNSET_VALUE is returned if time has never been incremented.
void ON_ParticleSystem::SetGlobalDragForce | ( | double | drag_coefficient1, |
double | drag_coefficient2, | ||
double | drag_coefficient3 | ||
) |
Description: Applies a cubic drag force of -(drag_coefficient1 + drag_coefficient2*|v| + drag_coefficient3*|v|^2)*v, where "v" is the particle's velocity. Parameters: drag_coefficient1 - [in] drag_coefficient2 - [in] drag_coefficient3 - [in]
void ON_ParticleSystem::SetGlobalGravityForce | ( | ON_3dVector | G | ) |
Description: Applies a force of ON_Particle.m_mass*G to every particle. Parameters: G - [in] Vector acceleration of gravity.
bool ON_ParticleSystem::SetStartTime | ( | double | start_time | ) |
Description: Sets the starting time. Parameters: start_time - [in] Remarks: The default starting time is zero. Once time has been incremented, the starting time cannot be set.