A simple Box or a Polygon can already be created but sometimes their size falls short …i.e. the  disk or particle (or some other polygon) may go beyond it. For that I am adding a ‘Straight-Plane’ object in the palette. Many intersecting Straight-Planes can be created on the scene at the same time. It will be like an infinite fixed surface which will provide a surface with which other objects may collide or slide/roll upon. Straight-PLane
The StraightPlane class will inherit from RigidBody and will have just two specific properties :
point1 (Vector2d)
point2 (Vector2d)
(…. just like we need two points to define a straight line in 2-D plane). The two points will decide its inclination and position.
But here lies the problem , How to keep the straight plane fom moving ?
We could take care of GravitationForce and Weightforce by setting its mass to zero.
to make sure that it doesnt move during collisions we could fix the values of ConstraintsInfo::DynSparseRowMatrix ::jacobian value  , to 1 (at the
correct offset of course..).
We will have to neutralise any force from being applied to it by any SPRING also.
All of this can be taken care of if in the StraightPlaneCreator class we create an ‘Anchor’ just
after the second point of the Plane is set by the user and call
Anchor::setBody() to set the Straight-Plane as the Object of that anchor . The plane will get added to the BodyList and the Anchor will
get added to the JointList of the StepCore::World class.
This way all the problem of keeping the straight-plane fixed will be solved without spreading any dirt around in the previous code.
The functions to check state of collision (Contacted, Separating, Separated, Colliding etc.) have been written.
Although I went through many papers and googled the phrase “Gilbert-johnson-keerthy Distance algorithm” over a hundred times, I still
could not “hundred-percent” understand how to check the state of collision for two polgons (and the code is a mile long..). Thankfully I dont have any use of it
at the moment.
The algorithm to find the state of collision with a Straight-Plane is quite simple. I am using the formula to find the
distance of a point in 2-D space from a straight-line.
if the equation of the line is (Ax + By + C = 0) and the given point is (x1, y1), then the distance of the point
from the straight-line is
abs(Ax1 + By1 + C)/sqrt(pow(A,2) + pow(B, 2))
The value of tolerance is to be checked with a little testing.
But I am having some trouble handling the mouseEvents on the scene ..(due to which StraightPlaneCreator and StraightPlaneGraphicsItem
classes are not yet functional. )
Also I dont know how to paint something that will extend itself with the view (the plane is supposed to be infinite and should
extend if the user scrolls…)
About Friction:
The documentation says :
>>>QHash provides very similar functionality to QMap. The differences are:
>>>QHash provides faster lookups than QMap. (See Algorithmic Complexity for details.)
When iterating over a QMap, the items are always sorted by key. With QHash, the items are arbitrarily ordered.
Therefore to store the friction-Coefficient and the restitution-Coefficient I am going to use a QHash as I need faster lookups
and at the same time no need to store keys in sorted-order.
Since there will be a ‘FrictionForce’ icon just like ‘Weightforce’ and ‘GravitationForce’ icons on the palette, I will need to
__REGISTER(FrictionForce) and __ADD_TO_PALETTE(FrictionForce) in the constructor of the WorldFactory Class.
There will be a QHash<QPair<RigidBody*, RigidBody*>, QPair<double, double>>
First double of the second QPair to store friction-coefficient and the second double to store the restitution-coefficient
for the pair of rigidbodies.
Or ther can be two QHash-es One for QHash<QPair<RigidBody*, RigidBody*>, double> (for friction-coefficient)
and another QHash<QPair<RigidBody*, RigidBody*>, double> (restitution-coefficient)
(but this will require searching for the same pair of RigidBody- pointers from two different QHashes , so I will go with the
first idea i.e. a single QHash).
I noticed one anomaly, the solveCollisions() function exists but is never called anywhere. I looked everywhere the
StepCore::World:: doEvolve() function led but didn’t find it being used anywhere. The collisions are being solved
by gathering the contacts information int a ‘ConstraintsInfo’ structure and then passing the structure to ConstraintSolver::solve()
function… I still have to do some study on the internals of that ConstraintSolver::solve() function (particularly the ei_constrained_cg() method from
Eigen::Unsupported module..)
But the place to add friction and coefficient of restitution (bounceness) would be in the CollisionSolver::getContactsInfo()
(which I am working on right now..)
SIMULATION:
I did some backtracking on Simulation Start/Stop button.
Step carries out simulation frame by frame. WorldModel contains a _simulationFps (int ) and a _simulationTimer (QTimer) whose interval is (currently) set to
(1000/_simulationFps) i.e. 40 milliseconds…( as the _simulationFps is set to 25 in the constructor of the WorldModel.)
simulationFrameBegin() calls _simulationThread->doWorldEvolve(1.0/_simulationFps) i.e. the ‘delta’ time value for world->doEvolve()
is 4o milliseconds ( same as the frame-width…).
On finishing world->doEvolve(), simulationThread emits the WorldEvelveDone signal which calls WorldModel::simulationFrameEnd(reault)
(result is the value returned by doEvolve()). and the GUI updated…
So Each frame is displayed after a gap of 40 milliseconds. (for _simulationFps = 25).
There is one more interesting thing in StepCore::World class . It is _timeScale. The runSpeedAction group exploits this
variable to make the simulation appear faster.
in World::doEvolve(delta) function targetTime = currentTime + delta * timescale .
So if the timescale is 2 or 4… targetTime becomes greater and while the _simulationTimer and frame-rate remain unaffected.
The outcome is:
If at 1x speed , after one frame you were seeing the state of the world after 40 milliseconds. (in reality also 40 milliseconds are allowed \
for the frame).
Then at 2x after one frame you would see the state of the world after 80 milliseconds. (but in reality only 40 milliseconds are allowed
for the frame).
Thus the simulation appears to go faster.
I am planning to test the simulation with increased values of _simulationFps (may be 40 or 50 ..or at-least 30)
or may be add this option in the configure-step menu item.
and may be convert the radio buttons for runspeed Action-Group to a slider (after all they are just changing the _timescale of the
StepCore::World class).
Â
Â
Â
Â
Â
Â
Â
Â
Â