Trilateration x-component is less than half the actual position - math

I'm using an array of ultrasonic receivers to estimate the location of an object, but the total length of the array is about 1 meter (all of them are on the same line).
By using the distance obtained, I tried using trilateration to see if I could estimate the position.
The problem starts here:
While the y-axis component of the position is reasonably close to the actual position, the x-axis component of the position is about half the actual position. In other words, if the actual position is (5,10)m, the obtained position is about (2.5,9.8)m.
The equation I used is
x = (r1^2 - r2^2 - x1^2 + x2^2) / (2*(x2-x1))
where r1 and r2 are the distances obtained for receiver 1 and receiver 2, and x1 and x2 are the x-coordinates of the receiver position.
I'm wondering if this is due to the small baseline, or if there's something about the math that I'm missing. Also, how should I go about fixing this problem?
I thought about just multiplying the x-component by 2, but it may just be a coincidence that it's about half the actual x-component right now.

Related

Calculating the angle tilt using only accelerometers

I would like to know how to calculate using the coordinates of the accelerometer of my Android phone the angle between the two segments connecting the accelerometer and the bottom of the tree (B) and the accelerometer and the top of the tree (T) .
The accelerometer takes a value of acceleration on 3 axes every second, so I calculated the average and I have:
For the phone towards B: Ay1 = -9.69m.s^-1 and Az1 = 0.71m.s^-1
For the phone towards T: Ay2 = -9.71m.s^-1 and Az2 = 0.71m.s^-1
I am located at a distance D = 20m from the tree.
I would like at the end to know the value of H. So I would like to know how to calculate the angle and then find the height of the tree.
Thanks for your help
The angles we need are the angles between world-up and device-up. Since the gravity vector is pointing towards world-down, this is simply (assuming, you are pointing with the device y-axis):
cos angle = -a.y / sqrt(a.x^2 + a.y^2 + a.z^2)
The two angles we get from your readings are:
angle1 = 4.19065°
angle2 = 4.18205°
You can already see that the angles are very close as the two acceleration values are also extremely close. Btw, I wonder if you are really pointing with the y-axis because the gravity values suggest that you are holding the phone almost upright in both cases.
Anyway, if we assume that the two angles are correct, we can now calculate the height of the respective triangles assuming a length to target l. Then:
tan (90° - angle) = h / l
Assuming l=20 m, this gives us two height values:
h1 = 272.958 m
h2 = 273.521 m
These are heights above the height of the phone. In theory, one should be positive and the other should be negative. The height of the tree would be the difference of the two heights:
treeH = h2 - h1
treeH = 0.56338 m
As you have seen throughout the example, your readings must be pretty off. Nevertheless, this is how you would calculate the tree height.

How to get the rotational speed around 2 axes by a given set of position vectors

I have a huge set of normalized position vectors. The vector-set is recorded by a special measurement device, while the device is rotate around two axes. Every position vector is also a combination of gravitational values for X, Y, and Z at a defined time. My assignment is to get the rotational speed of the both axes.
The coordinate system of the measurement device is rotated by circa 45° around the z-axis in relation to the coordinate system of machine.
The z-axis of the measurement device parallel to the z-axis of the machine.
I have tried to convert the carthesian coordinates to spherical coordinates. For this i used the Qt-Framework and MATLAB. As a result I got 2 angles and a radius. In my opinion the radius is not important. But the 2 angles don’t fit my problem, because I need the rotational speed of machine around the machine Z-axis and the X-axis. At this point it is important to know that the rotational speed is so slow that gravity-vector pointed always with 1g in to the ground. The X-,Y-, and Z-values of the measurement device represents the orientation subject to the gravity-vector . For example if the Z-axis pointed to the Ground the value is nearly 1. And if the axis is parallel to the ground (also orthogonal to the gravity-vecot) the value is nearly zero.
If the machine only rotates around the Z-axis I can get the period of one rotation very easy. The plot of the Y-values and X-values subject to the time is a sine or cosine. So I can get period by searching for the zero point, the maxima or the minima.
rotation around the z-axis
But this solution fit only the 1axis-problem. If the machine rotates additional around the X-axis the measured X-, Y-, and Z-values are combinations of both rotations. I have no idea how I can fix my problem.
rotation around the machines z-axis and x-axis: the rotation starts after 55s!
Another idea is the inverse kinematic but for this I need the dimensions of the machine and the exact point where the measurement device is mounted.
rotation around 1 axis
Dataset rotation around 1 axis
rotation around 2 axis
Dataset rotation around 2 axes
How can I start or go ahead?
I have tried to visualize the rotational process with this picture.
I tried to put this in as a comment, but there is a length limit there. So, some clarifying questions / intermediate conclusions:
Thanks for the figures! So it looks from your 4th figure above, the one showing 2-axis x-y-z sine waves, and from your diagram of the machine, like you have three coordinate systems: The first is the earth frame, call it x1,y1,z1, as you show it in "machine picture" diagram. The second frame call it x2,y2,z2 rotates about both the x1 and the x2 axes (they remain parallel). The third frame x3,y3,z3 is the one that rotates about the z2 (=z3) axis. Your accelerometers are fixed in the x3,y3,z3 coordinate frame.
Your single-axis data set has z3=z2 aligned with earth z1, and spins about z, so that x3 and y3 spin around sampling gravity in quadrature sine waves.
In your second data set, the outer gimbal x1=x2 rotates at a constant rate, giving rise to the perfect sine wave on the z accelerometer, while the inner z3=z2 gimbal also spins perhaps at a constant rate, but now the accelerometers on x3 and y3 have their amplitudes modulated by multiplying by the cosine of the x1/x2 rotation angle.
Does all this sound right?
One other thing we always need to know when estimating velocity from position measurements is some kind of model or concept of how your system changes in time: Can we assume some maximum angular acceleration? Or can we assume that once the rotation(s) come up to speed, that they are constant? That will become especially important in trying to stitch the z2/z3 gimbal angle over the times when the x1/x2 angle passes through +/-pi/2 radians, where the z2/z3 angle becomes momentarily unobservable because the x and y accelerometers are orthogonal to the gravity vector and will just show noise. It will also help us to decide if the x1/x2 gimbal went up to pi/2 and back down again, or kept turning in the same direction to > pi/2, because both motions look the same on the z accelerometer, and the z2/z3 angle is unobservable there.
Simple answer:
Use two-argument arctangent.
The roll angle is atan2(ay, ax).
The pitch angle is atan2(az, sqrt(ax*ax + ay*ay)).
Then time-difference these to get angle rates.
This oversimplified solution has a number of problems, but it's a good place to start.
Probably the key you need is this: You must transform the x and y accelerations from measurement coordinates to machine coordinates before estimating the pitch about the machine x axis. This requires you to first know the roll angle (about the machine z axis). In matlab sytax,
[x_machine; y_machine] = [cos(roll) -sin(roll); sin(roll) cos(roll)] * [x_meas; y_meas].
z_machine = z_meas, always.
Given x,y,z in machine coordinates, you can directly estimate the pitch angle and rate about the machine x axis:
pitch = atan2(z_machine, -y_machine) (right hand rule about the machine x axis; positive acceleration pointing down);
pitch_rate = -asin((xyz_i cross xyz_i-1)_x) / dt_i,
where in English, the rate is computed from the arcsine of the x_machine component of the cross product of the latest machine coordinate acceleration vector with the previous one, divided by the time between them (1/8 of a second in your case).
The same approach works for estimating roll and roll rate (about the machine z axis):
roll = atan2(-x_meas, -y_meas) * cos(pitch) / abs(cos(pitch));
roll_rate = -asin((xyz_meas_i cross xyz_meas_i-1)_z) * cos(pitch) / abs(cos(pitch)) / dt_i.
It is a chicken-and-egg problem, where you need to know the pitch and roll to estimate pitch and roll and their rates. So you need to start off with a good guess of the correct pitch and roll angles (to within 15 degrees or so should be fine).
All of the measurements are noisy, so the estimates will be also. The rate estimates especially so. So you will want to filter the estimates in time. Propagate your pitch and roll angle estimates in time using your filtered angle rate estimates.
Also, your roll angle and rate estimates become pure noise as pitch is near +/-pi/2, so you should probably weight down the inputs to the roll filters by something like cos^2(pitch).

how to measure the distance in dicom

I want to know how to measure the distance between two pixels in dicom . already done some google found pixel spacing (0028,0030) need to find the distance . could some one clearly explain ....
thanks
Assuming that you're trying to measure distances in the subject/animal/phantom/whatever, it all depends on whether you want to measure distances between different slices or just in the same slice.
Volumetric DICOM series typically have a slice spacing (0012,0088) in addition to the pixel spacing which you need to take into account. Note that there is also such a thing as slice thickness, which is distinct and should not be used for calculating distances, as there can be a gap or overlap between consecutive slices.
It is helpful to define a voxelspacing vector as follows (pseudocode):
voxelspacing.x = first element of PixelSpacing (0028,0030), i.e. before "\"
voxelspacing.y = second element of PixelSpacing (0028,0030), i.e. after "\"
voxelspacing.z = SliceSpacing (0018,0088) or 0 if 2D and/or not specified
Some brain-dead manufacturers and de-identification tools break the slice spacing tag in which case you'll have to calculate it from another source, such as difference in consecutive slice location, patient image position, etc, but that's another matter.
Moving on, you now have the distance in millimeters between voxels for each dimension. You can then calculate the real-world euclidean distance given voxel coordinates in pointA and pointB:
delta = (pointA - pointB) * voxelspacing
distance = sqrt(delta.x^2 + delta.y^2 + delta.z^2);
Where all the operators are element-wise. It is critical to individually multiply the voxel coordinates with their respective spacings before computing distance, because voxels are typically not isotropic.
You need to know the dot pitch of the monitor. For example a jumbotron has huge pixels (guessing), so the distance is larger than it would be for a typical desktop monitor. Ask the manufacturer of the monitor for this information. After that use pythogorean theorum. sqrt(a^2 + b^2) = c c being the total distance and a/b are x and y distances. to find a and be you would find the coordinates of one pixel and subtract from the other. a = (x1-x2) b = (

3D Trilateration using given distances of unknown fixed points

I am new to this forum and not a native english speaker, so please be nice! :)
Here is the challenge I face at the moment:
I want to calculate the (approximate) relative coordinates of yet unknown points in a 3D euclidean space based on a set of given distances between 2 points.
In my first approach I want to ignore possible multiple solutions, just taking the first one by random.
e.g.:
given set of distances: (I think its creating a pyramid with a right-angled triangle as a base)
P1-P2-Distance
1-2-30
2-3-40
1-3-50
1-4-60
2-4-60
3-4-60
Step1:
Now, how do I calculate the relative coordinates for those points?
I figured that the first point goes to 0,0,0 so the second one is 30,0,0.
After that the third points can be calculated by finding the crossing of the 2 circles from points 1 and 2 with their distances to point 3 (50 and 40 respectively). How do I do that mathematically? (though I took these simple numbers for an easy representation of the situation in my mind). Besides I do not know how to get to the answer in a correct mathematical way the third point is at 30,40,0 (or 30,0,40 but i will ignore that).
But getting the fourth point is not as easy as that. I thought I have to use 3 spheres in calculate the crossing to get the point, but how do I do that?
Step2:
After I figured out how to calculate this "simple" example I want to use more unknown points... For each point there is minimum 1 given distance to another point to "link" it to the others. If the coords can not be calculated because of its degrees of freedom I want to ignore all possibilities except one I choose randomly, but with respect to the known distances.
Step3:
Now the final stage should be this: Each measured distance is a bit incorrect due to real life situation. So if there are more then 1 distances for a given pair of points the distances are averaged. But due to the imprecise distances there can be a difficulty when determining the exact (relative) location of a point. So I want to average the different possible locations to the "optimal" one.
Can you help me going through my challenge step by step?
You need to use trigonometry - specifically, the 'cosine rule'. This will give you the angles of the triangle, which lets you solve the 3rd and 4th points.
The rules states that
c^2 = a^2 + b^2 - 2abCosC
where a, b and c are the lengths of the sides, and C is the angle opposite side c.
In your case, we want the angle between 1-2 and 1-3 - the angle between the two lines crossing at (0,0,0). It's going to be 90 degrees because you have the 3-4-5 triangle, but let's prove:
50^2 = 30^2 + 40^2 - 2*30*40*CosC
CosC = 0
C = 90 degrees
This is the angle between the lines (0,0,0)-(30,0,0) and (0,0,0)- point 3; extend along that line the length of side 1-3 (which is 50) and you'll get your second point (0,50,0).
Finding your 4th point is slightly trickier. The most straightforward algorithm that I can think of is to firstly find the (x,y) component of the point, and from there the z component is straightforward using Pythagoras'.
Consider that there is a point on the (x,y,0) plane which sits directly 'below' your point 4 - call this point 5. You can now create 3 right-angled triangles 1-5-4, 2-5-4, and 3-5-4.
You know the lengths of 1-4, 2-4 and 3-4. Because these are right triangles, the ratio 1-4 : 2-4 : 3-4 is equal to 1-5 : 2-5 : 3-5. Find the point 5 using trigonometric methods - the 'sine rule' will give you the angles between 1-2 & 1-4, 2-1 and 2-4 etc.
The 'sine rule' states that (in a right triangle)
a / SinA = b / SinB = c / SinC
So for triangle 1-2-4, although you don't know lengths 1-4 and 2-4, you do know the ratio 1-4 : 2-4. Similarly you know the ratios 2-4 : 3-4 and 1-4 : 3-4 in the other triangles.
I'll leave you to solve point 4. Once you have this point, you can easily solve the z component of 4 using pythagoras' - you'll have the sides 1-4, 1-5 and the length 4-5 will be the z component.
I'll initially assume you know the distances between all pairs of points.
As you say, you can choose one point (A) as the origin, orient a second point (B) along the x-axis, and place a third point (C) along the xy-plane. You can solve for the coordinates of C as follows:
given: distances ab, ac, bc
assume
A = (0,0)
B = (ab,0)
C = (x,y) <- solve for x and y, where:
ac^2 = (A-C)^2 = (0-x)^2 + (0-y)^2 = x^2 + y^2
bc^2 = (B-C)^2 = (ab-x)^2 + (0-y)^2 = ab^2 - 2*ab*x + x^2 + y^2
-> bc^2 - ac^2 = ab^2 - 2*ab*x
-> x = (ab^2 + ac^2 - bc^2)/2*ab
-> y = +/- sqrt(ac^2 - x^2)
For this to work accurately, you will want to avoid cases where the points {A,B,C} are in a straight line, or close to it.
Solving for additional points in 3-space is similar -- you can expand the Pythagorean formula for the distance, cancel the quadratic elements, and solve the resulting linear system. However, this does not directly help you with your steps 2 and 3...
Unfortunately, I don't know a well-behaved exact solution for steps 2 and 3, either. Your overall problem will generally be both over-constrained (due to conflicting noisy distances) and under-constrained (due to missing distances).
You could try an iterative solver: start with a random placement of all your points, compare the current distances with the given ones, and use that to adjust your points in such a way as to improve the match. This is an optimization technique, so I would look up books on numerical optimization.
If you know the distance between the nodes (fixed part of system) and the distance to the tag (mobile) you can use trilateration to find the x,y postion.
I have done this using the Nanotron radio modules which have a ranging capability.

Collision Detection between Accelerating Spheres

I am writing a physics engine/simulator which incorporates 3D space flight, planetary/stellar gravitation, ship thrust and relativistic effects. So far, it is going very well, however, one thing that I need help with is the math of the collision detection algorithm.
The iterative simulation of movement that I am using is basically as follows:
(Note: 3D Vectors are ALL CAPS.)
For each obj
obj.ACC = Sum(all acceleration influences)
obj.POS = obj.POS + (obj.VEL * dT) + (obj.ACC * dT^2)/2 (*EQ.2*)
obj.VEL = obj.VEL + (obj.ACC * dT)
Next
Where:
obj.ACC is the acceleration vector of the object
obj.POS is the position or location vector of the object
obj.VEL is the velocity vector of the object
obj.Radius is the radius (scalar) of the object
dT is the time delta or increment
What I basically need to do is to find some efficient formula that derives from (EQ.2) above for two objects (obj1, obj2) and tell if they ever collide, and if so, at what time. I need the exact time both so that I can determine if it is in this particular time increment (because acceleration will be different at different time increments) and also so that I can locate the exact position (which I know how to do, given the time)
For this engine, I am modelling all objects as spheres, all this formula/algorithm needs to do is to figure out at what points:
(obj1.POS - obj2.POS).Distance = (obj1.Radius + obj2.Radius)
where .Distance is a positive scalar value. (You can also square both sides if this is easier, to avoid the square root function implicit in the .Distance calculation).
(yes, I am aware of many, many other collision detection questions, however, their solutions all seem to be very particular to their engine and assumptions, and none appear to match my conditions: 3D, spheres, and acceleration applied within the simulation increments. Let me know if I am wrong.)
Some Clarifications:
1) It is not sufficient for me to check for Intersection of the two spheres before and after the time increment. In many cases their velocities and position changes will far exceed their radii.
2) RE: efficiency, I do not need help (at this point anyway) with respect to determine likely candidates for collisions, I think that I have that covered.
Another clarification, which seems to be coming up a lot:
3) My equation (EQ.2) of incremental movement is a quadratic equation that applies both Velocity and Acceleration:
obj.POS = obj.POS + (obj.VEL * dT) + (obj.ACC * dT^2)/2
In the physics engines that I have seen, (and certainly every game engine that I ever heard of) only linear equations of incremental movement that apply only Velocity:
obj.POS = obj.POS + (obj.VEL * dT)
This is why I cannot use the commonly published solutions for collision detection found on StackOverflow, on Wikipedia and all over the Web, such as finding the intersection/closest approach of two line segments. My simulation deals with variable accelerations that are fundamental to the results, so what I need is the intersection/closest approach of two parabolic segments.
On the webpage AShelley referred to, the Closest Point of Approach method is developed for the case of two objects moving at constant velocity. However, I believe the same vector-calculus method can be used to derive a result in the case of two objects both moving with constant non-zero acceleration (quadratic time dependence).
In this case, the time derivative of the distance-squared function is 3rd order (cubic) instead of 1st order. Therefore there will be 3 solutions to the Time of Closest Approach, which is not surprising since the path of both objects is curved so multiple intersections are possible. For this application, you would probably want to use the earliest value of t which is within the interval defined by the current simulation step (if such a time exists).
I worked out the derivative equation which should give the times of closest approach:
0 = |D_ACC|^2 * t^3 + 3 * dot(D_ACC, D_VEL) * t^2 + 2 * [ |D_VEL|^2 + dot(D_POS, D_ACC) ] * t + 2 * dot(D_POS, D_VEL)
where:
D_ACC = ob1.ACC-obj2.ACC
D_VEL = ob1.VEL-obj2.VEL (before update)
D_POS = ob1.POS-obj2.POS (also before update)
and dot(A, B) = A.x*B.x + A.y*B.y + A.z*B.z
(Note that the square of the magnitude |A|^2 can be computed using dot(A, A))
To solve this for t, you'll probably need to use formulas like the ones found on Wikipedia.
Of course, this will only give you the moment of closest approach. You will need to test the distance at this moment (using something like Eq. 2). If it is greater than (obj1.Radius + obj2.Radius), it can be disregarded (i.e. no collision). However, if the distance is less, that means the spheres collide before this moment. You could then use an iterative search to test the distance at earlier times. It might also be possible to come up with another (even more complicated) derivation which takes the size into account, or possible to find some other analytic solution, without resorting to iterative solving.
Edit: because of the higher order, some of the solutions to the equation are actually moments of farthest separation. I believe in all cases either 1 of the 3 solutions or 2 of the 3 solutions will be a time of farthest separation. You can test analytically whether you're at a min or a max by evaluating the second derivative with respect to time (at the values of t which you found by setting the first derivative to zero):
D''(t) = 3 * |D_ACC|^2 * t^2 + 6 * dot(D_ACC, D_VEL) * t + 2 * [ |D_VEL|^2 + dot(D_POS, D_ACC) ]
If the second derivative evaluates to a positive number, then you know the distance is at a minimum, not a maximum, for the given time t.
Draw a line between the start location and end location of each sphere. If the resulting line segments intersect the spheres definitely collided at some point and some clever math can find at what time the collision occurred. Also make sure to check if the minimum distance between the segments (if they don't intersect) is ever less than 2*radius. This will also indicate a collision.
From there you can backstep your delta time to happen exactly at collision so you can correctly calculate the forces.
Have you considered using a physics library which already does this work? Many libraries use far more advanced and more stable (better integrators) systems for solving the systems of equations you're working with. Bullet Physics comes to mind.
op asked for time of collision. A slightly different approach will compute it exactly...
Remember that the position projection equation is:
NEW_POS=POS+VEL*t+(ACC*t^2)/2
If we replace POS with D_POS=POS_A-POS_B, VEL with D_VEL=VEL_A-VEL_B, and ACC=ACC_A-ACC_B for objects A and B we get:
$D_NEW_POS=D_POS+D_VEL*t+(D_ACC*t^2)/2
This is the formula for vectored distance between the objects. In order to get the squared scalar distance between them, we can take the square of this equation, which after expansion looks like:
distsq(t) = D_POS^2+2*dot(D_POS,D_VEL)*t + (dot(D_POS, D_ACC)+D_VEL^2)*t^2 + dot(D_VEL,D_ACC)*t^3 + D_ACC^2*t^4/4
In order to find the time where collision occurs, we can set the equation equal to the square of the sum of radii and solve for t:
0 = D_POS^2-(r_A+r_B)^2 + 2*dot(D_POS,D_VEL)*t + (dot(D_POS, D_ACC)+D_VEL^2)*t^2 + dot(D_VEL,D_ACC)*t^3 + D_ACC^2*t^4/4
Now, we can solve for the equation using the quartic formula.
The quartic formula will yield 4 roots, but we are only interested in real roots. If there is a double real root, then the two objects touch edges at exactly one point in time. If there are two real roots, then the objects continuously overlap between root 1 and root 2 (i.e. root 1 is the time when collision starts and root 2 is the time when collision stops). Four real roots means that the objects collide twice, continuously between root pairs 1,2 and 3,4.
In R, I used polyroot() to solve as follows:
# initial positions
POS_A=matrix(c(0,0),2,1)
POS_B=matrix(c(2,0),2,1)
# initial velocities
VEL_A=matrix(c(sqrt(2)/2,sqrt(2)/2),2,1)
VEL_B=matrix(c(-sqrt(2)/2,sqrt(2)/2),2,1)
# acceleration
ACC_A=matrix(c(sqrt(2)/2,sqrt(2)/2),2,1)
ACC_B=matrix(c(0,0),2,1)
# radii
r_A=.25
r_B=.25
# deltas
D_POS=POS_B-POS_A
D_VEL=VEL_B-VEL_A
D_ACC=ACC_B-ACC_A
# quartic coefficients
z=c(t(D_POS)%*%D_POS-r*r, 2*t(D_POS)%*%D_VEL, t(D_VEL)%*%D_VEL+t(D_POS)%*%D_ACC, t(D_ACC)%*%D_VEL, .25*(t(D_ACC)%*%D_ACC))
# get roots
roots=polyroot(z)
# In this case there are only two real roots...
root1=as.numeric(roots[1])
root2=as.numeric(roots[2])
# trajectory over time
pos=function(p,v,a,t){
T=t(matrix(t,length(t),2))
return(t(matrix(p,2,length(t))+matrix(v,2,length(t))*T+.5*matrix(a,2,length(t))*T*T))
}
# plot A in red and B in blue
t=seq(0,2,by=.1) # from 0 to 2 seconds.
a1=pos(POS_A,VEL_A,ACC_A,t)
a2=pos(POS_B,VEL_B,ACC_B,t)
plot(a1,type='o',col='red')
lines(a2,type='o',col='blue')
# points of a circle with center 'p' and radius 'r'
circle=function(p,r,s=36){
e=matrix(0,s+1,2)
for(i in 1:s){
e[i,1]=cos(2*pi*(1/s)*i)*r+p[1]
e[i,2]=sin(2*pi*(1/s)*i)*r+p[2]
}
e[s+1,]=e[1,]
return(e)
}
# plot circles with radius r_A and r_B at time of collision start in black
lines(circle(pos(POS_A,VEL_A,ACC_A,root1),r_A))
lines(circle(pos(POS_B,VEL_B,ACC_B,root1),r_B))
# plot circles with radius r_A and r_B at time of collision stop in gray
lines(circle(pos(POS_A,VEL_A,ACC_A,root2),r_A),col='gray')
lines(circle(pos(POS_B,VEL_B,ACC_B,root2),r_B),col='gray')
Object A follows the red trajectory from the lower left to the upper right. Object B follows the blue trajectory from the lower right to the upper left. The two objects collide continuously between time 0.9194381 and time 1.167549. The two black circles just touch, showing the beginning of overlap - and overlap continues in time until the objects reach the location of the gray circles.
Seems like you want the Closest Point of Approach (CPA). If it is less than the sum of the radiuses, you have a collision. There is example code in the link. You can calculate each frame with the current velocity, and check if the CPA time is less than your tick size. You could even cache the cpa time, and only update when acceleration was applied to either item.

Resources