Gradient Of Bezier Curve At Given Point - algorithm

I cant seem to figure out how to calculate the incline of a curve for the following situation...
Essentially what I am trying to do is increase the speed of an object based on the incline of the curve at a particular point. The speed will be reduced if the incline is upwards and increase if downward.
I was using the derivative of a point t on the bezier curve to establish the tangent but this doesnt seem to be right as I would expect that value to be negative if the slope is downward.
I have been using the below equation for the tangent to evaluate X, Y and Z but then I only use Y to establish the incline...I think that step may be wrong
Any ideas?
EDIT:
Ultimately this is an object moving along an inclined plane but I cant establish the angle of the plane in order to do this, I believe if I could correctly find the angle it may solve the problem. I tried to take the point in question and then another point in front (so for example t = 0.5 and then a point in front would be t=0.51) and then calculate the angle using tan. I completely ignore the Z axis but is that wrong? If not how should I calculate the angle?
Thanks a lot

This should help: http://www.physicsclassroom.com/Class/vectors/U3L3e.cfm .
Essentially, you need to calculate the angle of inclination. If the angle is \theta , then the acceleration depends on sin(\theta).
I am assuming z as the vertical dimension.
if dx,dy and dz is are the gradients in each directions, dw = sqrt( dx^2+dy^2). \theta = tan_inverse( dz/dw). Acceleration = g*sin(\theta).
NOTE: You can directly calculate sin(\theta) without explicitly calculating \theta. sin(\theta) = dz/sqrt(dx^2+dy^2+dz^2).
=== More formal description ===
Let x be the east-west dimension, y be the north-south dimension and z be the up-down dimension.
Let z = F(x,y) give the elevation of the terrain at any given location x,y.
Calculate dz/dx = fx(x,y) and dz/dy = fy(x,y), the partial derivatives of z w.r.t to x and y.
Now, sin(\theta) = dz/sqrt(dx^2+dy^2+dz^2) = 1/(sqrt( (dx/dz)^2+ (dy/dz)^2 )= 1/(sqrt( (1/fx(x,y))^2, (1/fy(x,y))^2 ).
This is how you calculate sin(\theta).

The value of derivation is negative when the slope is "downward". And yes, the derivation is the tangent of the slope angle. Only you should pay attention to the directions. They can change the sign, of course. Only you should take dy/dx, not dy/something else. That is all on 2d curves.
You mention Z in the last paragraph. You curve is 3D? Then, of course, the term "derivation" should be put more precisely. Derivation of what to what do you need? The second idea is - please, explain better, what do you want. BTW, maybe after you write down the task correctly, you'll see the solution as obvious.
If it is 3D, let us say, you have your curve as 3 functions of x(t), y(t), z(t). then you need dz/dq, where dq= dt*sqrt((dx/dt)^2+(dy/dt)^2). Obviously, isn't it?
As I said, no maths here. Merely Pythagor's theorem and proportions. (I take z as height)
Addition: it can be rerecounted as tan(a)=dz/(dt*sqrt((dx/dt)^2+(dy/dt)^2)) => tan(a)=(dz/dt)/sqrt((dx/dt)^2+(dy/dt)^2)) ==> a=ATAN((dz/dt)/sqrt((dx/dt)^2+(dy/dt)^2)). But look out for directions you are moving! They can reverse the sign. For under sqrt(^2+^2) we have lost the direction of the dt proection.

Related

Fast Integer Coordinates Inside/along a Circle Centered at origin with radius r

Consider that you have a circle centered at 0,0 with radius r.
I'd like to get all the integer points available that are inside this circle. This problem is easy to solve.
One may just iterate over a square from x = -r to +r and y =-r to +r and see if x * x + y * y <= r * r, if so, add the point to your result.
However, what's the quickest way to do this? I feel there should be some type of hack that we can take the calculations from (2r)^2 to 4/3 r^2
More particularly, I have a feeling that we can calculate the length of the inscribed square, then add the outer remaining components. I'm unsure of how to do this though. The math is a little dense. I'm refraining from posting code because I'd like a general algorithm response, but if one has preference, he may state the final benchmark that this will be used in should use a JVM language.
Any help?
Note: this is similar to the gauss's circle problem, but instead of counting the number of points, I want to know what the points are.
You can get the values directly by computing the maximum y (the second coordinate of the point on the circle at the vertical of (x,0)) for each value of x like that:
for x in [-floor(r), floor(r)]
y_max = floor(sqrt(r^2 - x^2)) # Pythagora's theorem
for y in [-y_max, y_max]
# (x, y) is good !
I don't think you can do much better (maybe you can compute y_max faster but that won't be a big win) because anyway you have these points in the result.
EDIT:
This is in Pi*r^2 time, which is the least you can do since it's the number of points.
You can maybe save a few computations by doing only a quarter circle and getting the other ones by symmetry, but I'm not even sure it's faster, and it's certainly longer to write.

what is the algorithm to determine x and y for something so that it follows a curve between 2 keyframes?

back in uni i remember there being an algorithm that's use to calculate the x and y position of point between the x and y values of 2 key frames, i know the one for a straight line
x = ((KeyFrame2.x - KeyFrame1.x)/duration)*time
my understanding is that the difference between the the 2 key frames divided by the duration give you how how many units of measurement (be it pixels mostly), for every unit of time (normally 1 frame) so you just multiply that value by how far though the timeline is
ie.
x = ((KeyFrame2.x - KeyFrame1.x)/duration)*time
x = ((10 - 0)/10)*3
x = (10/10)*3
x = 1*3
x = 3 (after 3 units of time, the object's position will be +3 pixels along the x axis from KeyFrame1)
this one i understand however there i was also told about one that it used for curve paths, say a ball bouncing foward and the keyframes are when it hits the ground and when it's at the peek of it's bounce, this one is what i've forgotten and i have no idea where the hell my notes are for it
what i am asking is the algorithm used to calculate the x and y positions for an object with a path like this, i am asking for the mathematical algorithm which is code interdependent, what i'm trying to do is animate a number of orbs that will circle the center of the screen for a logo, i've got the objects in code to move however i need to adjust the calculations between keyframes
NOTE: even though i'm not asking for code, the algorithms are used in animation programming and as such my question relates to programming in general
NOTE2: KeyFrame2.x and KeyFrame1.x are not code, i see keyframes as an instance of a class which holds values such as x ,y, z, duration from previous frame ect
You're not asking for algorithms, you're asking for equations. You can use various equations based on what kind of motion you're simulating; for example, projectile motion under gravity is described by a parabola -- a curve of the form
x = a * y^2 + b
For motion controlled by some intelligent force, curve-fitting based on higher-order polynomials or Bezier curves are more appropriate. Google is your friend here.
If you know that you have circle movement you can circle equation to predict next position or to interpolate between. Since circle can be uniquely defined by 3 points, you need 3 points to interpolate in-between. It makes sense, having only 2 points you cant even know if it is convex or concave circle.
based on movement your points will have, you pick equation that is at least similar to movement you have. In most cases linear equation as you pointed out is just good enough.

Logarithmic plotting of points

I was wondering if give a number of 2D points, how do calculate where to draw a point on a screen in a logarithmic y scale?
I tried to just take the logarithm of all the y-values of points and than plot them 'normally' (plot point [x, log(y)] => on height: height*log(y)/log(max)). But this approach causes problems for y-values under 1. So this makes me wonder if my method in general is the right approach. A tweak i could maybe use would be to use log(y/min) instead of log(y).
Any advice on improvement or better approaches are welcome!
By assuming y values are positive, use your own approach with a small bias, like: height*log(y-min+1)/log(max-min+1) to prevent from very big negative values.
If you plot y/ymin logarithmically, you'll scale the smallest value to 1, guaranteeing that all the logarithmic values are non-negative.
Check out the R implementation of plot which may provide you with some clues. If you use plot(x,y,log='y') then y axis is plotted on log scale.
About points<1, you will face same problem with -ve numbers, right? So basically you need to normalize data such that all points are within visible range on the screen. Use the following transformation:
ny = number_of_pixels*(log(y) - min(log(Y)))/(max(log(Y))-min(log(Y)))
from what i understand, you seem to be trying to plot log(y) but keeping the y axis as it was for y? that doesn't really make sense.
the way you are plotting is fine: you plot a point at (x, log(y)).
but what you need to change is the limits of the y axis. if it originally went from ymin to ymax, it now needs to go from log(ymin) to log(ymax).
if you change the y axis limits that way then the points will fit in just fine.

Computing an angle from x,y coordinates [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Circle line collision detection
I'm trying to do collision testing between a finite line segment, and an arc segment. I have a collision test which does line segment vs. line segment, so I was going to approximate these arc segments with line segments and run my existing test.
The data I have defining the arc segment(s) are three points. Two of which are endpoints that lie on the circumference of a circle, and the third point is the center of that circle.
So far this is what I've got:
Let (a,b) be the center point of the circle, let 'r' be the radius of the circle, and (x1, y1), (x2, y2) be the endpoints of the arc segment which lies on the circumference of the circle.
The following parametric equations give the x, and y locations of an arc. 't' is the parametric variable.
x = a + r * cos(t)
y = b + r * sin(t)
To create the line segments from the arc, I wanted to walk the arc for some fixed ratio of 't' creating line segments along the way, until I've reached the end of the arc. To do this I figured I'd have to find the start and end angle. I'd start walking the arc from the start angle, and end at the end angle. Since I know the start and end points I figured I could use these equations to solve for these angles. The following are my equations for this:
t = arccos((x-a)/r)
or
t = acrcsin((y-b)/r)
The problem I'm having is that the range of values returned by these functions (http://en.wikipedia.org/wiki/Inverse_trigonometric_function) is limited, so there is a high probability that the angle I'm looking for will not be returned because these functions are multivalued: arcsin(0) = 0, but also arcsin(0) = π, arcsin(0) = 2π, etc
How do I get the exact angle(s) I'm looking for? Or, can you think of a better/different way of achieving my goal?
Take a look at the atan2 function, which should exist in whatever programming language or math library you're using. It takes two arguments, the x and y coordinates of a point (for you: (x-a)/r and (y-b)/r) and returns the angle in the range -π to +π.
At least IMO, you're going at this the wrong way. A line has an equation y=mx+b. A circle has an equation x2 + y2 = r2. You're looking for a point at which the x and y of the circle equals the x and y of the line. You can do that by substituting the mx+b equation for the line for the y equation in the circle, and then solve using the quadratic equation.
The equations involved do get a bit long, but quite a few web pages (e.g., http://www.sonoma.edu/users/w/wilsonst/papers/geometry/circles/default.html) have them, at which point it's simple matter of implementing the equations as a couple of functions and plugging in the values for your particular circle/line. A solution based on these equations complete avoids the ambiguity from using an arg tangent.
Your pseudo-code looks a lot like Python. If you don't mind using Python I would recommend the Shapely Library. If you just want the algorithm, check the source.
Shapely objects have the 'simplify' and 'intersection' methods.

Finding a minimum bounding sphere for a frustum

I have a frustum (truncated pyramid) and I need to compute a bounding sphere for this frustum that's as small as possible. I can choose the centre to be right in the centre of the frustum and the radius be the distance to one of the "far" corners, but that usually leaves quite a lot of slack around the narrow end of the frustum
This seems like simple geometry, but I can't seem to figure it out. Any ideas?
This is probably not the answer you're looking for, but you could compute all the verts of the frustum and plug them into a general minimum bounding sphere algorithm, like the miniball implementation.
Well, there's http://www.cgafaq.info/wiki/Minimal_enclosing_sphere of course (via Google).
I'd think there are two possibilities. One (if the frustum is very flat) would be that the opposite points of the base become opposite points on the sphere. The other (if the frustum is very tall) would be that opposite points of the frustum would be on the sphere and you'd figure out the sphere from those four points (one point on the base, one opposite the first on the base, one opposite the first on the higher square, one adjacent the first on the higher square).
Figure out the first sphere. If the frustum fits in it, that's your answer. Otherwise, the second sphere would be your answer.
There are several algorithms and implementations out there for this problem (see also this post).
For 2D and 3D, Gärtner's implementation is probably the fastest.
For higher dimensions (up to 10,000, say), take a look at https://github.com/hbf/miniball, which is the implementation of an algorithm by Gärtner, Kutz, and Fischer (note: I am one of the co-authors).
For very, very high dimensions, core-set (approximation) algorithms will be faster.
In your particular application, you may want to try either of the first two algorithms. Both run in O(n) with a very small constant and are numerically stable.
The way to do this is to find a sphere that fits 4 points on your frustum. If this is a proper frustum (a truncated pyramid - my bad I was assuming a cylindrical fristum), then you get two points from opposite corners of the top quad, and the other two from the bottom quad, out of phase with the top two. Then use this to get your sphere.
Well let's solve with math.
Using right hand Y up coordinate system (forward is –Z axis), for frustum with viewport width w, height h, near plane n, far plane f, X axis field of view angle fov, then the minimal bounding sphere is
k = sqrt(1+(h/w)^2) * tan⁡(fov/2)
if( k^2 >= (f-n)/(f+n) )
{
C = (0, 0, -f)
R = f*k
}
else
{
C = (0, 0, -0.5 * (f+n) * (1+k^2))
R = 0.5 * sqrt( (f-n)^2 + 2*(f^2+n^2)*k^2 + (f+n)^2*k^4 )
}
C is the center of the sphere, in view space, and R is radius.
I put details in my blog if you are interested:
https://lxjk.github.io/2017/04/15/Calculate-Minimal-Bounding-Sphere-of-Frustum.html
Any set of four noncoplanar points defines a sphere. Assuming you're using a four-sided pyramid for your frustum, there are 70 possible sets of four points. Try all 70 spheres and see which is the smallest.
Given that your frustum probably has some symmetries, you can probably pick the four points on opposite corners and use plinth's solution.
You need to find a point on a "vertical" line down the center of the frustum where the distance to an edge on the bottom and top of the frustum (assuming it's symmetrical) is the same.
solve such that a point on the bottom is Xb, Yb, Zb, a point on the top is Xt, Yt, Zt and the line is a point Xp, Yp, Zp plus a vector Ax, By, Cz.
so solve the equation
sqrt( (Xb - (Xp + VAx) )^2 + (Yb - (Yp + VBy))^2 + (Zb - (Zp + VCy))^2) =
sqrt( (Xt - (Xp + VAx) )^2 + (Yt - (Yp + VBy))^2 + (Zt - (Zp + VCy))^2).
The only variable in there is the scalar V.
Strictly speaking (according to this) the base of the frustum can be any polygon and, also strictly speaking, that polygon doesn't even have to be convex. That said, to get a general solution to the problem, I think you might need to use (almost) all the vertices as suggested above. There might be special cases, though, whose solution might (as suggested above) only require the comparison of a couple of spheres. I like the link by Anthony above: Megiddo provides a transformation that he claims yields a solution in O(n) (!) time. Not bad !

Resources