Time to turn 180 degrees - vb.net

I have a space ship, and am wanting to calculate how long it takes to turn 180 degrees. This is my current code to turn the ship:
.msngFacingDegrees = .msngFacingDegrees + .ROTATION_RATE * TV.TimeElapsed
My current .ROTATION_RATE is 0.15, but it will change.
I have tried:
Math.Ceiling(.ROTATION_RATE * TV.TimeElapsed / 180)
But always get an answer of 1. Please help.

To explain why you get 1 all the time:
Math.Ceiling simply rounds up to the next integer, so your sum contents must always be < 1.
Rearranging your sum gives TV.TimeElapsed = 180 * (1/.ROTATION_Rate). With a ROTATION_Rate of 0.15 we know that TV.TimeElapsed needs to reach 1200 before your overall function returns > 1.
Is it possible that you're always looking at elapsed times less than this threshold?
Going further to suggest what your sum should be is harder - Its not completely clear without more context.

Related

Calculation issue in Kotlin

So i am just doing a simple calculation in my app but somehow I'm not getting expected answer with the formula.
var i = 90 / 60 * 1000
This always returns 1000 instead of 1500
It seems some issue with the floating point from 90 / 60 operation, but I'm not sure how to handle it in Kotlin.
The whole number (integer) division 90 / 60 results in 1, namely the places in front of the decimal point. Better divide by a floating point number:
var i = 90 / 60f * 1000
// result: 1500.0

Math for VB.net Progressbar 0 to 100%

I can not figure out the math that allows me to use a progress bar from 0-100% when the number is in the one hundred thousands.
I've tried:
156761 / 100 = 1567.61
156761 * 100 = 15676100
And I can not come up with anything else that allows that large of a number to be in the range of 0-100%.
Not sure if I get your question correctly...
First, if what you want is to show a progressbar with some value that's not 100... why not simply set the progres bar's Maximum to your value (156761 in your example) and set Value to whatever progress it has?
Now, if the progress bar for whatever reason has to be fixed from 0 to 100, you can use:
x / m * 100
Where m is the max value and x the progress value.
If you have a maximum value
x / max_value
And you want to convert it to percent.
y / 100
Then you need to do
x * 100 / max_value = y
You would need to know the maximum value your progress could reach (maybe a million) and divide by this to get a percentage of progress. So if your max was 1000000 you might do 100000/1000000= 0.1 to give 10%.

Calculate two angles difference (3d game)

I want to record speed of angle movement in a 3D game.
So we have the X axis, where we move from 0-360 with no border, when we are on 359 and move further we hit 0 again.
The game stores the 0-360 in -180-180 instead of 0-360
To calculate the speed I have to record two stages and compare there difference with the time it took, to get the movement speed.
But how do I get the difference.
the difference from 80-120 is = 40 we can just calculate by minusing them.
but the difference from -175 to 175 is = 10, but how do I calculate that? Cause minus them will give -180, but the difference is actually 10.
Simply add 180 to each value and then take the absolute value of the difference.
Dim delta = Math.Abs((180 + final) - (180 + initial))
EDIT: Not sure whether you always want positive values and you want to differentiate between the direction, e.g. if the movement is 270 degrees in one direction is that actually 90 degrees in the other direction. I think that you actually need to define the problem a bit more clearly because it's open to interpretation at the moment.
One approach is to use a little trigonometry. I'm not entirely sure what the VB way of doing this is, so I'll just use pseudocode. If you assume a1=175 and a2=-175, this should work.
θ1 ← a1 * π / 180
θ2 ← a2 * π / 180
δ ← acos( cos(θ1)*cos(θ2) + sin(θ1)*sin(θ2) ) * 180 / π
If you are averse to the use of the trigonometry, you can use some conditionals instead
if a1 < 0 then
θ1 ← 360 - ((-a1) mod 360)
else
θ1 ← a1 mod 360
if a2 < 0 then
θ2 ← 360 - ((-a2) mod 360)
else
θ2 ← a2 mod 360
δ ← ( MAX(θ1, θ2) - MIN(θ1, θ2) ) mod 360
if δ > 180 then
δ ← 360 - δ
Both of these will return δ the smallest angle between the two angles (i.e. it will be in the range [0, 180]). You'll probably get better performance with the second method though there may be some edge cases you also need to check.
angle1 and angle2 are in the range -179...180 and the difference should return the smallest in absolute value among the numbers
(angle2-angle1)+k*360
where k varies over the integers. So to the difference (175-(-175))=350 some other associated candidates are -730, -370, -10, 710. Obviously, the sought after result would be -10.
The range of the difference in the first term in general is -359...359, so to get a result without sign indefiniteness, in a first step add 360+180=540 and compute the now guaranteed positive remainder mod 360
diff = (angle2-angle1+540) mod 360
The inserted 360 cancels under the mod operation, the 180 gives a shift of +180 that must be removed in the final result
diff = diff - 180
is now in the range -180...180 as required.
In the example, this calculates as
diff = (175-(-175)+540) % 360 - 180
= 890 % 360 -180
= 170 - 180
= -10
as required.
The other way around, exchanging 175 and -175,
diff = (-175-175+540) % 360 - 180
= (-350+540) % 360 - 180
= 190 % 360 - 180
= 190 - 180
= 10
I made a solution:
Private Function Calcdif(ByVal firstAngle As Single, ByVal secondAngle As Single) As Single
Dim difference As Single = secondAngle - firstAngle
Select Case difference
Case Is < -180
difference += 360
Case Is > 180
difference -= 360
End Select
If secondAngle = firstAngle Then
Return 0
Else
Return (Math.Abs(difference))
End If
End
End Function

Efficiently finding the distance between 2 lat/longs in SQL

I'm working with billions of rows of data, and each row has an associated start latitude/longitude, and end latitude/longitude. I need to calculate the distance between each start/end point - but it is taking an extremely long time.
I really need to make what I'm doing more efficient.
Currently I use a function (below) to calculate the hypotenuse between points. Is there some way to make this more efficient?
I should say that I have already tried casting the lat/longs as spatial geographies and using SQL built in STDistance() functions (not indexed), but this was even slower.
Any help would be much appreciated. I'm hoping there is some way to speed up the function, even if it degrades accuracy a little (nearest 100m is probably ok).
Thanks in advance!
DECLARE #l_distance_m float
, #l_long_start FLOAT
, #l_long_end FLOAT
, #l_lat_start FLOAT
, #l_lat_end FLOAT
, #l_x_diff FLOAT
, #l_y_diff FLOAT
SET #l_lat_start = #lat_start
SET #l_long_start = #long_start
SET #l_lat_end = #lat_end
SET #l_long_end = #long_end
-- NOTE 2 x PI() x (radius of earth) / 360 = 111
SET #l_y_diff = 111 * (#l_lat_end - #l_lat_start)
SET #l_x_diff = 111 * (#l_long_end - #l_long_start) * COS(RADIANS((#l_lat_end + #l_lat_start) / 2))
SET #l_distance_m = 1000 * SQRT(#l_x_diff * #l_x_diff + #l_y_diff * #l_y_diff)
RETURN #l_distance_m
I haven't done any SQL programming since around 1994, however I'd make the following observations:The formula that you're using is a formula that works as long as the distances between your coordinates doesn't get too big. It'll have big errors for working out the distance between e.g. New York and Singapore, but for working out the distance between New York and Boston it should be fine to within 100m.I don't think there's any approximation formula that would be faster, however I can see some minor implementation improvements that might speed it up such as (1) why do you bother to assign #l_lat_start from #lat_start, can't you just use #lat_start directly (and same for #long_start, #lat_end, #long_end), (2) Instead of having 111 in the formulas for #l_y_diff and #l_x_diff, you could get rid of it there hence saving a multiplication, and instead of 1000 in the formula for #l_distance_m you could have 111000, (3) using COS(RADIANS(#l_lat_end)) or COS(RADIANS(#l_lat_start)) won't degrade the accuracy as long as the points aren't too far away, or if the points are all within the same city you could just work out the cosine of any point in the cityApart from that, I think you'd need to look at other ideas such as creating a table with the results, and whenever points are added/deleted from the table, updating the results table at that time.

Is there an iterative way to calculate radii along a scanline?

I am processing a series of points which all have the same Y value, but different X values. I go through the points by incrementing X by one. For example, I might have Y = 50 and X is the integers from -30 to 30. Part of my algorithm involves finding the distance to the origin from each point and then doing further processing.
After profiling, I've found that the sqrt call in the distance calculation is taking a significant amount of my time. Is there an iterative way to calculate the distance?
In other words:
I want to efficiently calculate: r[n] = sqrt(x[n]*x[n] + y*y)). I can save information from the previous iteration. Each iteration changes by incrementing x, so x[n] = x[n-1] + 1. I can not use sqrt or trig functions because they are too slow except at the beginning of each scanline.
I can use approximations as long as they are good enough (less than 0.l% error) and the errors introduced are smooth (I can't bin to a pre-calculated table of approximations).
Additional information:
x and y are always integers between -150 and 150
I'm going to try a couple ideas out tomorrow and mark the best answer based on which is fastest.
Results
I did some timings
Distance formula: 16 ms / iteration
Pete's interperlating solution: 8 ms / iteration
wrang-wrang pre-calculation solution: 8ms / iteration
I was hoping the test would decide between the two, because I like both answers. I'm going to go with Pete's because it uses less memory.
Just to get a feel for it, for your range y = 50, x = 0 gives r = 50 and y = 50, x = +/- 30 gives r ~= 58.3. You want an approximation good for +/- 0.1%, or +/- 0.05 absolute. That's a lot lower accuracy than most library sqrts do.
Two approximate approaches - you calculate r based on interpolating from the previous value, or use a few terms of a suitable series.
Interpolating from previous r
r = ( x2 + y2 ) 1/2
dr/dx = 1/2 . 2x . ( x2 + y2 ) -1/2 = x/r
double r = 50;
for ( int x = 0; x <= 30; ++x ) {
double r_true = Math.sqrt ( 50*50 + x*x );
System.out.printf ( "x: %d r_true: %f r_approx: %f error: %f%%\n", x, r, r_true, 100 * Math.abs ( r_true - r ) / r );
r = r + ( x + 0.5 ) / r;
}
Gives:
x: 0 r_true: 50.000000 r_approx: 50.000000 error: 0.000000%
x: 1 r_true: 50.010000 r_approx: 50.009999 error: 0.000002%
....
x: 29 r_true: 57.825065 r_approx: 57.801384 error: 0.040953%
x: 30 r_true: 58.335225 r_approx: 58.309519 error: 0.044065%
which seems to meet the requirement of 0.1% error, so I didn't bother coding the next one, as it would require quite a bit more calculation steps.
Truncated Series
The taylor series for sqrt ( 1 + x ) for x near zero is
sqrt ( 1 + x ) = 1 + 1/2 x - 1/8 x2 ... + ( - 1 / 2 )n+1 xn
Using r = y sqrt ( 1 + (x/y)2 ) then you're looking for a term t = ( - 1 / 2 )n+1 0.36n with magnitude less that a 0.001, log ( 0.002 ) > n log ( 0.18 ) or n > 3.6, so taking terms to x^4 should be Ok.
Y=10000
Y2=Y*Y
for x=0..Y2 do
D[x]=sqrt(Y2+x*x)
norm(x,y)=
if (y==0) x
else if (x>y) norm(y,x)
else {
s=Y/y
D[round(x*s)]/s
}
If your coordinates are smooth, then the idea can be extended with linear interpolation. For more precision, increase Y.
The idea is that s*(x,y) is on the line y=Y, which you've precomputed distances for. Get the distance, then divide it by s.
I assume you really do need the distance and not its square.
You may also be able to find a general sqrt implementation that sacrifices some accuracy for speed, but I have a hard time imagining that beating what the FPU can do.
By linear interpolation, I mean to change D[round(x)] to:
f=floor(x)
a=x-f
D[f]*(1-a)+D[f+1]*a
This doesn't really answer your question, but may help...
The first questions I would ask would be:
"do I need the sqrt at all?".
"If not, how can I reduce the number of sqrts?"
then yours: "Can I replace the remaining sqrts with a clever calculation?"
So I'd start with:
Do you need the exact radius, or would radius-squared be acceptable? There are fast approximatiosn to sqrt, but probably not accurate enough for your spec.
Can you process the image using mirrored quadrants or eighths? By processing all pixels at the same radius value in a batch, you can reduce the number of calculations by 8x.
Can you precalculate the radius values? You only need a table that is a quarter (or possibly an eighth) of the size of the image you are processing, and the table would only need to be precalculated once and then re-used for many runs of the algorithm.
So clever maths may not be the fastest solution.
Well there's always trying optimize your sqrt, the fastest one I've seen is the old carmack quake 3 sqrt:
http://betterexplained.com/articles/understanding-quakes-fast-inverse-square-root/
That said, since sqrt is non-linear, you're not going to be able to do simple linear interpolation along your line to get your result. The best idea is to use a table lookup since that will give you blazing fast access to the data. And, since you appear to be iterating by whole integers, a table lookup should be exceedingly accurate.
Well, you can mirror around x=0 to start with (you need only compute n>=0, and the dupe those results to corresponding n<0). After that, I'd take a look at using the derivative on sqrt(a^2+b^2) (or the corresponding sin) to take advantage of the constant dx.
If that's not accurate enough, may I point out that this is a pretty good job for SIMD, which will provide you with a reciprocal square root op on both SSE and VMX (and shader model 2).
This is sort of related to a HAKMEM item:
ITEM 149 (Minsky): CIRCLE ALGORITHM
Here is an elegant way to draw almost
circles on a point-plotting display:
NEW X = OLD X - epsilon * OLD Y
NEW Y = OLD Y + epsilon * NEW(!) X
This makes a very round ellipse
centered at the origin with its size
determined by the initial point.
epsilon determines the angular
velocity of the circulating point, and
slightly affects the eccentricity. If
epsilon is a power of 2, then we don't
even need multiplication, let alone
square roots, sines, and cosines! The
"circle" will be perfectly stable
because the points soon become
periodic.
The circle algorithm was invented by
mistake when I tried to save one
register in a display hack! Ben Gurley
had an amazing display hack using only
about six or seven instructions, and
it was a great wonder. But it was
basically line-oriented. It occurred
to me that it would be exciting to
have curves, and I was trying to get a
curve display hack with minimal
instructions.