Related
this is my first question on the forum and my algebra is rusty so please be indulgent ^^'
So my problem is that i want to predict collision between two uniform circular motion objects for which i know velocity (angular speed in radian), distance from the origin (radius), cartesian coordinate of the center of the circle.
I can get cartesian position for each object given for t time (timestamp) using :
Oa.x = ra X cos(wa X t)
Oa.y = ra X sin(wa X t)
Oa.x: Object A x coordinates
ra: radius of a Circle A
wa: velocity of object A (angular speed in radian)
t: time (timestamp)
Same goes for object b (Ob)
I want to find t such that ||Ca - Cb|| = (rOa + rOb)
rOa: radius of object a
Squaring both side and expanding give me this :
||Ca-Cb||^2 = (rOa+rOb)^2
(ra * cos (wa * t) - rb / cos (wb * t))^2 + (ra * sin (wa * t) - rb / sin (wb * t))^2 = (ra+rb)^2
From that i should get a quadratic polynomial that i can solve for t, but how can i find a condition that tell me if such a t exist ? And possibly, how to solve it for t ?
Your motion equations are missing some stuff I expect this instead:
a0(t) = omg0*t + ang0
x0(t) = cx0 + R0 * cos(a0(t))
y0(t) = cy0 + R0 * sin(a0(t))
a1(t) = omg1*t + ang1
x1(t) = cx1 + R1 * cos(a1(t))
y1(t) = cy1 + R1 * sin(a1(t))
where t is time in [sec], cx?,cy? is the center of rotation ang? is starting angle (t=0) in [rad] and omg? is angular speed in [rad/sec]. If the objects have radius r? then collision occurs when the distance is <= r0+r1
so You want to find smallest time where:
(x1-x0)^2 + (y1-y0)^2 <= (r0+r1)^2
This will most likely lead to transcendent equation so you need numeric approach to solve this. For stuff like this I usually use Approximation search so to solve this do:
loop t from 0 to some reasonable time limit
The collision will happen with constant frequency and the time between collisions will be divisible by periods of both motions so I would test up to lcm(2*PI/omg0,2*PI/omg1) time limit where lcm is least common multiple
Do not loop t through all possible times with brute force but use heuristic (like the approx search linked above) beware initial time step must be reasonable I would try dt = min(0.2*PI/omg0,0.2*PI/omg1) so you have at least 10 points along circle
solve t so the distance between objects is minimal
This however will find the time when the objects collide fully so their centers merge. So you need to substract some constant time (or search it again) that will get you to the start of collision. This time you can use even binary search as the distance will be monotonic.
next collision will appear after lcm(2*PI/omg0,2*PI/omg1)
so if you found first collision time tc0 then
tc(i) = tc0 + i*lcm(2*PI/omg0,2*PI/omg1)
i = 0,1,2,3,...
This question is for learning purpose. I am writing my own function to plot an equation. For example:
function e(x) { return sin(x); }
plot(e);
I wrote a plot function that takes function as parameter. The plotting code is simple, x run from some value to some value and increase by small step. This is plot that the plot() manage to produce.
But there is the problem. It cannot express the circle equation like x2 + y2 = 1. So the question would be how should the plot and equation function look like to be able to handle two variables.
Noted that I am not only interesting in two circle equation. A more generalize way of plotting function with two variables.
Well to plot a non function 1D equation (x,y variables) you have 3 choices:
convert to parametric form
so for example x^2 + y^2 = 1 will become:
x = cos(t);
y = sin(t);
t = <0,2*PI>
So plot each function as 1D function plot while t is used as parameter. But for this you need to exploit mathematic identities and substitute ... That is not easily done programaticaly.
convert to 1D functions
non function means you got more than 1 y values for some x values. If you separate your equation into intervals and divide to all cases covering whole plot then you can plot each derived function instead.
So you derive y algebraicaly (let assume unit circle again):
x^2 + y^2 = 1
y^2 = 1 - x^2
y = +/- sqrt (1 - x^2)
----------------------
y1 = +sqrt (1 - x^2)
y2 = -sqrt (1 - x^2)
x = <-1,+1>
this is also not easily done programaticaly but it is a magnitude easier than #1.
do a 2D plot using equation as predicator
simply loop your view through all pixels and render only those for which the equation is true. So again unit circle:
for (x=-1.0;x<=+1.0;x+=0.001)
for (y=-1.0;y<=+1.0;y+=0.001)
if (fabs((x*x)+(y*y)-1.0)<=1e-6)
plot_pixel(x,y,some_color); // x,y should be rescaled and offset to the actual plot view
So you just convert your equation to implicit form:
x^2 + y^2 = 1
-----------------
x^2 + y^2 - 1 = 0
and compare to zero with some threshold (to avoid FPU accuracy problems):
| x^2 + y^2 - 1 | <= threshold_near_zero
The threshold is half size of plot lines width. So this way you can easily change plot width to any pixel size... As you can see this is easily done programaticaly but the plot is slower as you need to loop through all the pixels of the plot view. The step for x,y for loops should match pixel size of the view scale.
Also while using equation as predicate you should handle math singularities as with blind probing you will most likely hit some like division by zero, domain errors for asin,acos,sqrt,etc.
So for arbitrary 1D non function use #3. unless you got some mighty symbolic math engine for #1 or #2.
Defination of a function : A function f takes an input x, and returns a single output f(x).
Now it means for any input there will be one and only one unique output. Like y = sin(x). this is a function on x and y definnes that function.
For equaltion like (x*x) + (y*y) = 1. there are two possible values of y for a single value of `x, hence it can not be termed as a valid equaltion for a function.
If you need to draw it then one possible solution is to plot two points for a single value of x, i.e. sqrt(1-(x*x)) and other -1*sqrt(1-(x*x)). Plot both the values (one will be positive other will be negative with the same absolute value).
really i have a problem to calculate first , second , third derivative on 3d image with matlab.
i have 60 slice of dicom format of knee mri , and i wanna calculate derivative .
for 2d image when we want to calculate derivative on x or y direction ,for example we use sobel or another operator in x direction for calculate derivative on x direction .
but in 3d image that i have 60 slices of dicom format , how can i calculate first, second ,and third derivative on x ,y,z directions .
i implement like this for first derivative :
F is 3d matrix that has all slices. [k,l,m] = size(F);
but i think it's not true .please help me , really i need your answers .
how can we calculate first, second, third derivative on x ,y ,z directions .?
case 'x'
D(1,:,:) = (F(2,:,:) - F(1,:,:));
D(k,:,:) = (F(k,:,:) - F(k-1,:,:));
D(2:k-1,:,:) = (F(3:k,:,:)-F(1:k-2,:,:))/2;
case 'y'
D(:,1,:) = (F(:,2,:) - F(:,1,:));
D(:,l,:) = (F(:,l,:) - F(:,l-1,:));
D(:,2:l-1,:) = (F(:,3:l,:)-F(:,1:l-2,:))/2;
case 'z'
D(:,:,1) = (F(:,:,2) - F(:,:,1));
D(:,:,m) = (F(:,:,m) - F(:,:,m-1));
D(:,:,2:m-1) = (F(:,:,3:m)-F(:,:,1:m-2))/2;
There is a function for that! Look up https://www.mathworks.com/help/images/ref/imgradient3.html, where there are options to indicate the kind of gradient computation: sobel is the default.
If you'd like directional gradients, consider using https://www.mathworks.com/help/images/ref/imgradientxyz.html, which has the same options available, but returns the directional gradients Gx, Gy and Gz.
volData = load('mri');
sz = volData.siz;
vol = squeeze(volData.D);
[Gx, Gy, Gz] = imgradientxyz(vol);
Note that these functions were introduced in R2016a.
The "first derivative" in higher dimensions is called a gradient vector. There are many formulas to numerically approximate the gradient, and one of the most accurate approaches is disccused in a recent paper: "High Order Spatial Generalization of 2D and 3D Isotropic Discrete Gradient Operators with Fast Evaluation on GPUs" by Leclaire et al.
Higher order derivatives in more than one dimension are tensors. The "second derivative" in particular is a rank-2 tensor and has 6 independent components, which to the lowest order approximation are
Dxx(x,y,z) = (F(x+1,y,z) - 2*F(x,y,z) + F(x-1,y,z))/2
Dyy(x,y,z) = (F(x,y+1,z) - 2*F(x,y,z) + F(x,y-1,z))/2
Dzz(x,y,z) = (F(x,y,z+1) - 2*F(x,y,z) + F(x,y,z-1))/2
Dxy(x,y,z) = (F(x+1,y+1,z) - F(x+1,y-1,z) - F(x-1,y+1,z) + F(x-1,y-1,z))/4
Dxz(x,y,z) = (F(x+1,y,z+1) - F(x+1,y,z-1) - F(x-1,y,z+1) + F(x-1,y,z-1))/4
Dyz(x,y,z) = (F(x,y+1,z+1) - F(x,y+1,z-1) - F(x,y-1,z+1) + F(x,y-1,z-1))/4
The "third derivative" will be a rank-3 tensor and will have even more components. The formulas are lenghty and can be derived by considering a Taylor series expansion of F up to the 3rd order
I'm trying to add a fade effect to my form by manually changing the opacity of the form but I'm having some trouble calculating the correct value to increment by the Opacity value of the form.
I know I could use the AnimateWindow API but it's showing some unexpected behavior and I'd rather do it manually anyways as to avoid any p/invoke so I could use it in Mono later on.
My application supports speeds ranging from 1 to 10. And I've manually calculated that for a speed of 1 (slowest) I should increment the opacity by 0.005 and for a speed of 10 (fastest) I should increment by 0.1. As for the speeds between 1 and 10, I used the following expression to calculate the correct value:
double opSpeed = (((0.1 - 0.005) * (10 - X)) / (1 - 10)) + 0.1; // X = [1, 10]
I though this could give me a linear value and that that would be OK. However, for X equal 4 and above, it's already too fast. More than it should be. I mean, speeds between 7, and 10, I barely see a difference and the animation speed with these values should be a little more spaced
Note that I still want the fastest increment to be 0.1 and the slowest 0.005. But I need all the others to be linear between them.
What I'm doing wrong?
It actually makes sense why it works like this, for instance, for a fixed interval between increments, say a few milliseconds, and with the equation above, if X = 10, then opSpeed = 0.1 and if X = 5, then opSpeed = 0.47. If we think about this, a value of 0.1 will loop 10 times and a value of 0.47 will loop just the double. For such a small interval of just a few milliseconds, the difference between these values is not that much as to differentiate speeds from 5 to 10.
I think what you want is:
0.005 + ((0.1-0.005)/9)*(X-1)
for X ranging from 1-10
This gives a linear scale corresponding to 0.005 when X = 1 and 0.1 when X = 10
After the comments below, I'm also including my answer fit for a geometric series instead of a linear scale.
0.005 * (20^((X-1)/9)))
Results in a geometric variation corresponding to 0.005 when X = 1 and 0.1 when X = 10
After much more discussion, as seen in the comments below, the updates are as follows.
#Nazgulled found the following relation between my geometric series and the manual values he actually needed to ensure smooth fade animation.
The relationship was as follows:
Which means a geometric/exponential series is the way to go.
After my hours of trying to come up with the appropriate curve fitting to the right hand side graph and derive a proper equation, #Nazgulled informed me that Wolfram|Alpha does that. Seriously amazing. :)
Wolfram Alpha link
He should have what he wants now, barring very high error from the equation above.
Your problem stems from the fact that the human eye is not linear in its response; to be precise, the eye does not register the difference between a luminosity of 0.05 to 0.10 to be the same as the luminosity difference between 0.80 and 0.85. The whole topic is complicated; you may want to search for the phrase "gamma correction" for some additional information. In general, you'll probably want to find an equation which effectively "gamma corrects" for human ocular response, and use that as your fading function.
It's not really an answer, but I'll just point out that everyone who's posted so far, including the original question, are all posting the same equation. So with four independent derivations, maybe we should assume that the equation was probably correct.
I did the algebra, but here's the code to verify (in Python, btw, with offsets added to separate the curves:
from pylab import *
X = arange(1, 10, .1)
opSpeed0 = (((0.1 - 0.005) * (10 - X)) / (1 - 10)) + 0.1 # original
opSpeed1 = 0.005 + ((0.1-0.005)/9)*(X-1) # Suvesh
opSpeed2 = 0.005*((10-X)/9.) + 0.1*(X-1)/9. # duffymo
a = (0.1 - 0.005) / 9 #= 0.010555555555... # Roger
b = 0.005 - a #= -0.00555555555...
opSpeed3 = a*X+b
nonlinear01 = 0.005*2**((2*(-1 + X))/9.)*5**((-1 + X)/9.)
plot(X, opSpeed0)
plot(X, opSpeed1+.001)
plot(X, opSpeed2+.002)
plot(X, opSpeed3+.003)
plot(X, nonlinear01)
show()
Also, at Nazgulled's request, I've included the non-linear curve suggested by Suvesh (which also, btw, looks quite alot like a gamma correction curve, as suggested by McWafflestix). The Suvesh's nonlinear equation is in the code as nonlinear01.
Here's how I'd program that linear relationship. But first I'd like to make clear what I think you're doing.
You want the rate of change in opacity to be a linear function of speed:
o(v) = o1*N1(v) + o2*N2(v) so that 0 <= v <=1 and o(v1) = o1 and o(v2) = o2.
If we choose N1(v) to equal 1-v and N2(v) = v we end up with what you want:
o(v) = o1*(1-v) + o2*v
So, plugging in your values:
v = (u-1)/(10-1) = (u-1)/9
o1 = 0.005 and o2 = 0.1
So the function should look like this:
o(u) = 0.005*{1-(u-1)/9} + 0.1*(u-1)/9
o(u) = 0.005*{(9-u+1)/9} + 0.1*(u-1)/9
o(u) = 0.005*{(10-u)/9} + 0.1(u-1)/9
You can simplify this until you get a simple formula for o(u) where 1 <= u <= 10. Should work fine.
If I understand what you're after, you want the equation of a line which passes through these two points in the plane: (1, 0.005) and (10, 0.1). The general equation for such a line (as long as it is not vertical) is y = ax+b. Plug the two points into this equation and solve the resulting set of two linear equations to get
a = (0.1 - 0.005) / 9 = 0.010555555555...
b = 0.005 - a = -0.00555555555...
Then, for each integer x = 1, 2, 3, ..., 10, plug x into y = ax+b to compute y, the value you want.
I am trying to build a function grapher,
The user enters xmin, xmax, ymin, ymax, function.
I got the x, y for all points.
Now i want to translate this initial referential to a Canvas starting at 0,0 up to
250,250.
Is there a short way or should i just check
if x < 0
new x = (x - xmin) * (250 / (xmax - xmin)) ?
etc ..
Also this basic approach does not optimise sampling.
For example if my function f(x) = 5 i dont need to sample the xrange in 500 points,
i only need two points. I could do some heuristic checks.
But for a function like sin(2/x) i need more sampling around x (-1,1) how would you aproach such a thing ?
Thanks
Instead of iterating over x in the original coordinates, iterate over the canvas and then transform back to the original coordinates:
for (int xcanvas = 0; xcanvas <= 250; i++) {
double x = ((xmax - xmin) * xcanvas / 250.0) + xmin;
double y = f(x);
int ycanvas = 250 * (y - ymin) / (ymax - ymin) + .5;
// Plot (xcanvas, ycanvas)
}
This gives you exactly one function evaluation for each column of the canvas.
You can estimate the derivative (if you have one).
You can use bidirectional (dichotomic) approach: estimate the difference and split the segment if necessary.
I think I would start by reasoning about this in terms of transformations from canvas to maths contexts.
(canvas_x, canvas_y) -> (maths_x, maths_y)
(maths_x, maths_y) -> (canvas_x, canvas_y)
maths_x -> maths_y
You iterate over the points that a displayable, looping over canvas_x.
This would translate to some simple functions:
maths_x = maths_x_from_canvas_x(canvas_x, min_maths_x, max_maths_x)
maths_y = maths_y_from_maths_x(maths_x) # this is the function to be plotted.
canvas_y = canvas_y_from_maths_y(maths_y, min_maths_y, max_maths_y)
if (canvas_y not out of bounds) plot(canvas_x, canvas_y)
Once you get here, it's relatively simple to write these simple functions into code.
Optimize from here.
I think that for this approach, you won't need to know too much about sample frequencies, because you sample at a rate appropriate for the display. It wouldn't be optimal - your example of y = 5 is a good example, but you'd be guaranteed not to sample more than you can display.