Getting position & rotation in parent space - rotation

I have few bones.
Bone001:
Bone002:
The are aligned in the same direction. Bone001 has an rotation (in both World and Parent space). Bone002 has the same rotation as Bone001 in World space and it's rotation in Parent space (Boone001) is 0.
I want to get the position and rotation of Bone002 in Parent space (which should be 0).
I have tried (according to official documentation):
--each and every returns the same World space pos (as $Bone002.transform.pos)
(in coordsys parent $Bone002.transform.pos)
(in coordsys local $Bone002.transform.pos)
(in coordsys $Bone001 $Bone002.transform.pos)
$Bone002.transform.pos *= inverse $Bone002.transform
But each and every of them returns the Bone002 World space position (and not the Parent space one). Same for rotation.

You were close with the last one, to get transformation in another object's space, multiply by the inverse of that object's transform. Here, that would be:
obj.transform.pos * inverse obj.parent.transform

Related

Method for finding all cubes of size L in a viewing frustum?

I am trying to find or search for a method that quickly finds all cubes of size L that would be contained by a viewing frustum. Maybe even using cuda.
I have made a DDA traversal for raycasting, which is like a 1D case to me and simple, as I only move along the line at a known distance.
My instinct was to create a bounding box of the frustum, and subdivide this space into a spatial grid of size L cubes. Then test each cell's center of the grid for being inside the frustum. Considering the frustum is a pyramid, it seems that about half the cells would be occupied by a bounding box and I feel that this method is just doing too much work. It will surely work though, I am hoping for a less naive or faster geometric approach.
Perhaps ray cast the left wall first, then right wall second and then line cast in between these? So in a nutshell, looking for the R3 version of something like a DDA traversal.
The fastest way to detect if a vertex resides within a frustum is dot product. The frustum consists of 4 planes, that is top, bottom, left, right, and two z values, front and back clipping. For each vertex check two things: First, is it outside front or back panel? And if not, is it inside the four planes?
To check if a vertex is outside front or back panel you check vertex.Z against your frustrum:
isInsideZ = vertex.Z >= frustrum.Zmin && vertex.Z <= frustrum.Zmax;
To check if it's inside the four frustrum 'walls' you need to compute the cross vectors for them, oriented towards the frustrum's center. Then check the dot product of each cross vector and the position vector to your vertex relative to the respective plane. You obtain this position vector by subtracting some arbitrary point on the plane from the vertex you test. Should the dot product be positive, the vertex is above that plane.
isAbove[i] = Vector3D.Dot(cross[i], vertex - planeloc[i]) > 0;
Where planeloc[i] is any point located on the respective plane i.
The vertex is inside the frustrum if all conditions are met:
isInside = isInsideZ && isAbove[0] && isAbove[1] && isAbove[2] && isAbove[3];
This sounds a bit awkward to handle, but a lot of things can be done outside the grinding loop, such as computing the cross products, i.e. frustrum plane normals, or the plane location vectors. For example, if a plane is spanned by (1,0,0), (1,1,0) then (1,0,0) already represents a point located on that plane.

Separation Axis Theorem MVT along only one axis

I am having trouble calculating 3D penetration vector along one axis. I already implemented SAT and it works. I want to calculate how much i need to offset first box from other so it will always sit on top of other. Kind of doing simple box cast with very long box.
How should i proceed with finding offset which would push one object in direction of specified axis.
The first part of this you should already know; when you project each shape onto each axis, there should be some min and max scalar value for shape A, let's say AMIN and AMAX, and the same for shape B (BMIN / BMAX).
If the objects are apparently colliding on an axis, their projections will overlap, meaning either AMIN < BMIN < AMAX < BMAX or BMIN < AMIN < BMAX < AMAX. Let's assume the first.
The value of AMAX-BMIN is the distance needed to move either shape to bring them into touching contact, and the axis being tested gives you the direction.
Usually, as one iterates through all of the axes, one tracks the minimum value and its corresponding axis, and that becomes the vector needed to un-collide the shapes. (Usually called the 'minimum displacement vector' if you want to Google it.)
For you, wanting to displace them in a specific direction, you would just store the value corresponding to that specific axis, and that becomes your displacement vector (which would then be added to one shape's position to separate them).
I highly recommend Googling "minimum displacement vector sat" and checking out the first few links, specifically this one: http://www.dyn4j.org/2010/01/sat/. It's a bit dense, but it's where I learned everything I know about SAT.
EDIT And...I missed a piece. This is kinda rough, but if you're wanting to displace the shapes along one axis (vertical in your example), based on a displacement vector gained from another axis (the normal of the long side of the bottom box), you need to project the displacement vector onto the desired (normalized) axis (using dot product) to get the proper distance, then combined with your desired axis.

How to calculate (count) number of orbits from positional data?

I have the x,y position of a body that makes roughly circular orbits around a known point. Is there an algorithm that will give me the number of orbits this body makes over time if I feed it a vector of x,y positions? I don't care about variations in the distance of the body from the "origin" of the orbit.
EDIT 1:
My solution so far:
shift the x,y coords of the body by the x,y position of the orbit origin (i.e. make origin of orbit [0,0])
compute atan2 of body xy to get radians, then convert to degrees
shift degrees so that 0 is start location of body
find all turn points in degree vector (find 359->0 transitions)
count orbits as number of turn points + remainder
The following algorithm assumes that there are more than 2 positions stored per orbit, with a spacing of less than 180 degrees.
Basically you define a "finishing line" for the orbit using the first position and increment a count when the body crosses it, which you can detect when the sign of the dot product of the position vector with the line normal changes:
Take the vector from the known point the body is orbiting around to the first position in your series and find a vector perpendicular to it. In 2D you can do this just by subtracting the center point from the first position, then swapping the x and y components and negating one of them. This vector defines the normal to the "finishing line" of each orbit.
Take the vector from the center to second position in the series, and find the dot product with the normal calculated above by multiplying component-wise.
Initialize an orbit count to zero
For each remaining position in the series:
Compute the vector from the center to the position, and the dot product of it with the finishing line normal. If the sign of the dot product the same as that of the second position, and different to the previous position in the series, increase the count by one.
You can work out the fractional part by calculating the angle between the last position and the first.

How to calculate time of passing the discrete path of cells?

Let's say we have a field of descrete cells (2d array or table). We have some finite path inside of it with no self-crossings and no diagonal connections. The particle starts its way in the point A and follows the pattern to the point B. One step can be done in the finite amount of time = t. So the time for the whole path will be T = t * l, where l = number of cells in the path. But! We have some cells in the field marked as 'h' and 'v'. If the particle hit the 'h' cell then it divides into 3 particles. One continue moving by the path. Second starts to move left from the 'h' cell to the left border of the field. Third starts to move right from the 'h' cell to the right border of the field. Analogically with the 'v' cell, but instead of left/right, another 2 particles start move up/down. All particles are moving simultaneously with the same speed. Additional particles can collect 'h' and 'v' too and also can be divided and spawn more particles. Need to write function in Lua that calculates time from the moment of first particle starts its way to the moment of all particles finished their ways. See related illustation. Note that once 'h' or 'v' cell have been collected it becomes a simple cell and other particles doesn't divide if hitting it.
There's not much of an algorithm that can be done here apart from the direct running of the simulations.
There can be no apriori knowledge of the simulation time since the movement of different particles alters the conditions for other particle movement (as in during harvest act).
If the v and h tiles remained after the interaction process then you could just perform a simple raytracing i.e. scan the route, find v and h tiles scan the lines drawn from v andh tiles, find v,h or border tiles, calculate the longest path, draw lines from newfound v,h and scan those, and so on until all lines hit the border or lock into loop. To ignore looped results you could memorize which tiles have been already visited by currently examined ray and its predecessors.
Obviously, as special tiles (v,h) can only prolong the simulation time, the result from above would give upper limit of time in simulation with disappearing special tiles. To calculate the exact runtime, you'd need to take into account the moment in time at which a particular tile is triggered. Surely, it is possible to do that with rays, but a little of thought is needed that it'd be an equivalent to a direct simulation of particles.
The code for that is pretty simple and I will only briefly outline algorithm:
%make array for particlesenter code here
particles={}
%define initial particle route
route={{x1,y1},{x2,y2},...}
%probably you should have your field defined somewhere here too
v_tiles={{x1,y1},{x2,y2}...}
h_tiles=...
%make particle, possible implementations are numerous really
%for example it could be represented by its position
%and a function which gives next position, based on current one
%for main particle it could search the route table for a current position and return next element,
%or just use external counter variable to keep track of propagation
particle={position={x,y}, propagator=function({x,y}) ....}
%put that into particles array obviously
%initialize counter
T=0
%run a cycle until there are particles
while #particles>0 do
%perform a single step for all the particles
for _,p in pairs(particles) do
%move them all
p.position=p.propagator(p.position)
endfor
%then check them all
for i,p in pairs(particles) do
%check for special tiles
if is_v(p.position) then
%make new particle
table.insert(particles,{
position={p.position.x, p.position.y+1},
%for secondary particles propagator would be just a constant addition to a single coordinate
propagator=function(pos) return {pos.x,pos.y+1} end
})
%make second new particle
%same for h tiles
if is_h(p.position) then ...
%check for border tile
if is_border(p.position) then
%remove those that are at the border
table.remove...
%for the original particle you'd have to check
%whether it has reached destination
%probably you should check that somewhere around here too
endfo
%do what we're here for: increase counter
T=T+1
endwhile
%when this reaches the end T will be the answer
It is good that when you're solving the problems in lua, you have machine powerful enough to not worry about memory footprint and just fire away with the variable size array. But for the current task it is possible to get rough upper limit for memory as : 1+2*( num_v+num_h ).
Once again, in direct simulation you might have less particles, but since every interaction with special tile removes special tile and adds a pair of particles, you will never have more than that.

Method for combining tiled squares defined as points into vectors

If I tile squares, and the squares can be defined by their coordinates, how can I simplify shapes made of multiple squares into vectors that define each edge of the entire shape? Pseudo-code or general terms are fine.
The first thing I can think of is (probably not the most efficient way) :
1) Get the bounding box of your entire tiling - which is min(x), min(y) to max(x), max(y) for all x and y of your tiles
2) For every row, start with STATE==EMPTY, iterate over each column : STATE changes to FULL when you hit a square, and EMPTY when you find a hole. Every time STATE goes from EMPTY to FULL, save the left hand line segment of that square and every time STATE goes from FULL to EMPTY, save the right hand line segment of that square.
3) Repeat above in the Y axis
Now you have a set containing only the outermost line segments, you can combine those that are co-linear etc and get the overall shape.
This will work for non-convex shapes and also if you have holes in your tiling.

Resources