How to find average velocity and acceleration of Bezier Spline ? - algorithm

In my application, I have few screen coordinates through which I draw a Bezier Spline and I need to find the average Velocity and acceleration through that spline.
How should I go about it ?
I will find it in terms of pixel/sec and pixels/square-sec.
and then convert it to m/sec and m/sec sq once the User provides pixel-meter mapping.
But How will I get the velocity or accn as I cant just take start point and end point, It has to be thru that curve.

Ughh, leave the pixel/sex and the pixels/square-sec approach aside for now.
I'm assuming from your question that you have an x-y plot with some sort of Bezier spline, some sort of curve which represents way over time. The x axis usually represents time, while the y axis represents way (length) s.
Velocity is the derivation of length over time, and acceleration the derivation of that. A derivation is simply the ratio of dy/dx in a (preferably) close pair of points.
So, what you need for a start is to interpolate and gather as many points from that Bezier spline. Leaving that up to you. From there,
dy = y(i+1) - yi
dx = x(i+1) - xi
velocity = dy/dx
So a graph of velocity over time would be that plotted on a time basis. Same goes for accelleration, just repeat the process.

You need to differentiate the curve once with respect to the temporal dimension in your plot (here I am assuming the x-axis/horizontal axis represents time; the y-axis/vertical axis represents distance travelled) to gain the local velocity component. Differentiate twice with respect to the same temporal dimension to get the acceleration at a given point. This is basically working out the gradient at each point along the curve for velocity, and the gradient of velocity to get the rate of change of velocity, namely acceleration.
To do this you use numerical integration to get the new quantities (velocity and acceleration) at each discreet point (or coordinate) on your spline based upon the data surrounding that point/coordinate location.

Related

Algorithm to predict pen/mouse input

I'm looking for an appropriate algorithm that reliably predicts input coordinates given by a digital stylus (e.g. Surface Pen). In my application, I'm given the coordinates of the input as x and y coordinates on the screen (together with their timestamps).
Given a list of events ordered chronologically, my aim is to find the coordinate of the "next" events.
The simple algorithm I came up with is using weighted average. Here is some code that illustrates it (in real code I use more than just 4 points):
class Point{
double x;
double y;
double timestamp;
}
// this contains 4 points
// in chronological order
vector<Point> points;
// predict using simple weighted average
// the subtraction operation is simply subtraction on x and y coordinates
Point diff1 = points[1]-points[0];
Point diff2 = points[2]-points[1];
Point diff3 = points[3]-points[2];
// add a weighted difference to the last point we have
Point predictedPoint = points[3] + diff1 * 0.2 + diff2 * 0.3 + diff3 * 0.5;
This doesn't work as well as I would like to as often the predicted input is not very accurate. So I would like to find something better that estimates the next input based on previous points (it'd be nice if this accounted for the velocity of inputs as well).
Unfortunately not a go to answer but merely some solution directions to consider.
One option is to plot the coordinates as a function of time and calculate the trendline (see e.g. https://math.stackexchange.com/questions/204020/what-is-the-equation-used-to-calculate-a-linear-trendline)
In your case the X axis would be the time component and the Y axis either the X or Y coordinate, so you'll end up with 2 functions. Take T=0 for the first timespan and the rest of the X axis in seconds.
This solution will only work with somewhat linear movements (maybe a zigzag) only. The issue with this approach however is that when let's say you draw half a circle the next predicted point will try to make an S curve because you average only known points.
Another option would be to differentiate the slope. Lets say you want to draw a hexagon, then the slope of your first line will be 0deg, second line 60deg, 3rd line 120deg, 4th 180deg, 5th 270deg, 6th=1St 360=0deg. In this case your X,Y coordinates go all over the place but the difference in slope is every time 60deg. Same applies to drawing a circle but the steps are infinitely smaller (this is actually one of the methods to calculate pi)
Now if you would just calculate the slope over the actual X,Y coordinates you'll basically end up with the same kind of algorithm as in your initial code. Basically you want to calculate the acceleration (using same method as described in the beginning of this answer), see e.g. https://blog.prepscholar.com/acceleration-formula-equation, and then calculate the trendline over the acceleration.
But also this solution is not fool proof. If your pencil trace is a zigzag then both your direction and acceleration will go nuts on every corner and your prediction will make no sense.
My advice would be to record a number of strokes, plot the result in a number of graphs and try some different formula's and methods to see which gives the best result.

Calculating the rotation vector of a sphere

I'm trying to calculate the axis of rotation of a ball which is moving and spinning at the same time, i.e. I want the vector along the axis that the ball is spinning on.
For every frame I know the x, y and z locations of 3 specific points on the surface of the sphere. I assume that by looking at how these 3 points have moved in successive frames, you can calculate the axis of rotation of the ball, however I have very little experience with this kind of maths, any help would be appreciated!
You could use the fact that the direction a position vector moves in will always be perpendicular to the axis of rotation. Therefore, if you have two position vectors v1 and v2 at successive times (for the same point), use
This gives you an equation with three unknowns (the components of w, the rotation axis). If you then plug in all three points you have knowledge of you should be able to solve these simultaneous equations and work out w.

Transform Matrix for ECEF to site co-ordinates

I am given site co-ordinate systems having the following parameters:
Projection Type (usually Transverse Mercator)
Ellipsoid/Datum (usually GRS80/GDA94)
Central Meridian
Central Scale Factor
False Easting
False Northing
and then need to programmatically convert a large number of points from ECEF into the site co-ordinate system, so ideally I'd like to use a transform matrix.
Wikipedia gives the formula for this transform matrix as:
http://upload.wikimedia.org/math/6/c/5/6c5e10c1708acc1663d618c2f3fecc98.png
But how do I calculate the parameters needed for this formula from the site mapping parameters I have been given?
The usual way to do this conversion is to first convert from ECEF to geodetic coordinates (latitude,longitude,height), and then to convert these to map coordinates (northing,easting,height). Each of these transforms is non-linear. However if the site is not too large and your accuracy requirements not too stringent, you could carry out the above transforms on a few dozen (say) points round the perimeter of the site, and then use these points and the original to find an affine transform that best approximates the map coordinates from the ECEF coordinates.
I've played around with this a bit and it appears that while it is possible to get the eastings and northings with fair accuracy (eg a couple of centimetres over a site within a circle of radius 10km and a 20m height variation over the site; but if the height variation is 200m the accuracy drops to 2 decimetres), it is not possible to get even fair accuracy on the height -- in the example the height could be ~8m in error. This is unavoidable, as a line of constant height in site coordinates will be close to a circular arc, and if you compute the greatest distance of the chord from the arc for an arc of length 20km and a circle of radius earth radius you get ~16m.

Calculating radius of smallest circle encompassing a North-East/Sout-West based bounding rectangle on Earth

I have a webpage that I am using a Google Map on. When the user drags the map and lets go, I need to query a server for all data points that fall within the bounds of the visible region of the map. I can quite easily get the North-East and South-West coordinate of the visible region of the map through the javascript API, essentially providing a bounding rectangle. However on the server, I am relying on a database whose geographic query API only supports queries in the form of a center point and a radius. So basically what I would like to do is figure out the minimum radius circle I would need to at least encompass the North-East and South-West points.
The simplest algorithm I thought of involved finding the center point between the NE and SW coordinate and then measuring the radius as the distance from the center point to either the NE or SW coordinate. In a simple euclidean space I'd be comfortable doing this, but I think I'd probably get something wrong with the Earth's non-flat coordinate system. I haven't even been able to convince myself that if I knew that centerpoint that the distance would be the same between the center and NE and the center and SW.
I've come across algorithms for smallest circles on a flat 2D surface and also algorithms describing the opposite i.e. bounding box from circle center and radius. I haven't come across a concise algorithm for this particular problem though.
I assume what you call the east-west and north-south coordinates are the longitude and latitude. You can convert them to Cartesian points and find the midpoint between the edge points of your region. This will yield a point C' below Earth's surface with the same latitude and longitude as your centre point C. (This will only work if the difference of your longitudes is smaller than 180°, however; otherwise you'll get a point on the opposite side of the earth, but with the same latitude.) If you need Cartesian coordinates for your centre point, you can project C' onto the surface by adjusting the radius to find your new centre point.
The distance bewteen the two points on the surface of Earth can be calculated with the great-circle disnatce formula.
Transformation is easy if you assume that Earth is a perfect sphere with radius R = 6373 km:
x = R * cos(lat) * cos(lon)
y = R * cos(lat) * sin(lon)
z = R * sin(lat)
and back:
lon = atan2(y, x)
lat = atan2(z, r) with r = sqrt(x*x + y*y)
(But Earth does not have a constant radius, so you might want to use a better coordinate system, maybe ECEF as explained in this answer if you need more precision.)
My first thought was to find your midpoint in terms of longitude and latitude, which should be okay if you take care of wrapping for the latitude. Then you calculate your distance accpording to the great-circle formula. But averaging the longitudes and latitudes does not seem to be sensible if your map region includes a pole.

Gradient Of Bezier Curve At Given Point

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.

Resources