I have a function to return the total length of a NavMesh path, using Vector3.SqrMagnitude to avoid the overhead of the Sqrt calculation in Vector3.Distance:
float DistanceAlongPath(NavMeshPath path)
{
float sum = 0;
for (int x = 0; x < path.corners.Length - 1; x++)
{
sum += Vector3.SqrMagnitude(path.corners[x + 1] - path.corners[x]);
}
return sum;
}
When the path only has two points the calculation seems fine, however at 3 points or more it always returns a smaller value for a long line than it does for a short line of only 2 points.
The distance shown in the first image is 3848, in the second it's 3419 despite being a much longer path.
Vector3.Distance works correctly with any number of points.
Am I missing something?
SqrMagnitude gives only an approximation of length. While values of SqrMagnitude can be compared to each other for relative length comparison, they do not give a true length, so you can't just combine them.
The root of your problem here is in the math, specifically in the order in which addition and multiplication are handled:
(5+5+5)^2 != (5^2 + 5^2 + 5^2)
For example, if you have 3 line segments, each of length 5, each will have SqrMagnitude of 25. Add them and you get 115.
Now consider a single line segment with length 15. SqrMagnitude is 225.
In either case, if you apply the square root operation to get a true length, you get the same result. 3*Sqrt(25) == 1*Sqrt(225)
Related
Problem:
I know the x and y of three arbitrary points on a 2d plane.
I know the vague distance from each point to the unknown, though I don't know the x y components.
I want to find the position of the 4th point.
The data is stored in a list >3 of type Data where
public class Data
{
double m_x, m_y, m_distance;
}
I've tried:
Walking the list, calculating the components of the distance, then adding the known x and y. I then calculated the average position of the predicted point from the 3 known points, but the accuracy was inconsistent.
foreach (var item in data_list)
{
var dx = item.m_x + item.m_distance * Math.Cos(item.m_distance);
var dy = item.m_y + item.m_distance * Math.Sin(item.m_distance);
out_list.Add(new Data { m_x = dx, m_y = dy });
}
foreach (var item in out_list)
{
__dx += item.m_x;
__dy += item.m_y;
}
__dx /= return_list.Count;
__dy /= return_list.Count;
Creating three circles at the known x and y, extending their radii equal to the distance component and checking intersection. The problem is that the distance varies since its rather imprecise, more like a suggestion.
Is there a simple, ok-performing, witty solution to this problem that I can't grasp?
I've thought of extending lines 360 degrees around each point and checking where three lines intersect, the shortest distance away from the origin, but I'm not entirely sure about the implementation.
I wrote this simple rounding method in C#, which will round any floating point number (input) to the nearest multiple of any target number (target):
float RoundToFloat(float input, float target)
{
float quotient = input / target;
if (quotient - Mathf.Floor(quotient) < .5)
{
return Mathf.Floor(quotient) * target;
}
else
{
return Mathf.Ceil(quotient) * target;
}
}
However this seems to break when the input is a negative number. What do I have to do to make it work? I've tried calculating the absolute value of the quotient, and flipping whether I use ceil / floor if the input is negative, but keep getting weird results either way.
Any advice would be much appreciated!
Got it ... you need to reverse the applications of Floor and Ceiling for negative numbers, because the rounding has to be in the 'correct direction' with respect to 0.
Floor always goes more negative, while Ceiling does the opposite.
You can do this with a "simple" addition to your if: an "iff", also known as "Boolean equals".
if (quotient - Mathf.Floor(quotient) < .5) ==
(quotient >= 0) {
I am computing the distance of an object.
The X and Y position values first stored in two different Lists X and W.
Then I use another List for storing the distance covered by this object. Also, I refresh the lists if their count reaches 10, in order to avoid memory burden.
On the basis of distance value, I have to analyze, if the object is in the static position the distance should not increases. And on the text box display, the computed distance values appears to be static.
Actually, I am using sensors to compute the distance. And due to sensor error even if the object is in the static state the distance value varies. The sensor error threshold is about to be 15cm.
I have developed the logic, However, I receive error:
System.ArgumentOutOfRangeException: 'Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index'
My code is as follows:
void distance()
{
List<double> d = new List<double>();
double sum = 0, sum1 = 0;
for (int i = 1; i < X.Count; i++)
{
//distance computation
if ((d[i] - d[i -1]) > 0.15)
{
sum1 = d.Sum();
sum = sum1 + dis1;
Dis = Math.Round(sum, 3);
}
}
// refresh the Lists when X, W and d List reach the count of 10
}
}
You do it totally wrong. Come up with a method computing a distance for a two given points. That's gonna be a func of signature double -> double -> double or, if you prefer C#, double ComputeDistance(double startPoint, double endPoint).
Then the only thing to do is to apply such a fuction to each pair of points you got. The easiest and most compact way to accomplish that is by means of Linq. It could be done in a regular foreach as well.
Take a note that it would be a way clearer if you will eventually merge your separated lists into a single list. Tuple<double, double> seems to be the best choice including performance.
As is in the question title, I am looking for an efficient way to represent a set of float values between (and including) values x and y, in a set of doubles from 0-1 where x is equal to 0 and y is equal to 1. Then fill in the values in between.
Let's assume x is 5 and y is 20.
Now, 5 = 0, 20 = 1.
Is there a mathematical function to determine the value of 10 in c#?
I feel like I just can't think of a way to do this programmatically where I can interchange the values of x and y. The values given for x and y will be single digits. Values ranging from 0-1 should have an accuracy of 2 decimal values. Any help is appreciated, thank you!
You could create your own function which takes x and y with a third parameter being your value you want to map and then return it like:
Static double Map(float x, float y, float inputValue){ Return Convert.ToDouble((inputValue-x)/(y-x));}
From a logical standpoint, you are trying to find what fraction the way your InputValue is between x and y. Imagine a long road with someone somewhere in the middle. To find what fraction the way he is along, you must find how far he has travelled, which is his position minus the starting position, then divide that by the total distance of the road, which would be in this case y(the end) -x(the starting position)
Currently I am writing my thesis and I was confronted with a behavior of .Net C# that I had never seen before. I am talking about an error in a calculation.
I implemented this formula:
1/2 * (Theta i-1 + Theta i) + Sum(Alph k, k=1, i-1)
This formula is applied to 4 objects. Theta is in all objects declared as float with the value 1,5708. Alpha is initialized with 0 and will be increased by each iteration.
First implmentation
float alpha = 0;
float value = 0;
for (int sphereCount = 1; sphereCount < this.spheres.Count; sphereCount++)
{
value = (1/2) * (this.spheres[sphereCount - 1].Theta + this.spheres[sphereCount].Theta);
alpha += value;
}
With this version value is always 0.0!
So I changed it to:
Working implementaion
float alpha = 0;
float value = 0;
for (int sphereCount = 1; sphereCount < this.spheres.Count; sphereCount++)
{
value =(this.spheres[sphereCount - 1].Theta + this.spheres[sphereCount].Theta) * 1/2;
alpha += value;
}
By removing the brackets around the 1/2 and placing it at the end of the calculation it worked.
WHY IS THAT SO???
It seems when you place 1/2 in brackets not depending on the position of 1/2 the result is 0.0. But also when i place (1/2) at the end it results in 0.0.
Does anyone here have an idea why?
This
(1 / 2)
evaluates to 0 because it's integer division. If you say
(1 / 2f)
or
(1 / (float) 2)
you'll be fine because it forces float divsion. Or, even better, just write 0.5.
If you write 1/2 the result is calculated using integer division that gives an integer result. You can force a floating point division by changing one of the numbers to a floating point number, as in 1/2f.
Or you could just write 0.5 which IMHO is more readable than 1/2.
Why multiply by 1? Rather than this:
value =(this.spheres[sphereCount - 1].Theta + this.spheres[sphereCount].Theta) * 1/2;
why not write this:
value =(this.spheres[sphereCount - 1].Theta + this.spheres[sphereCount].Theta) / 2;
You should write 1.0/2 or 0.5 instead 1/2.
1/2 is an integer division which results in an integer 0.
Because 1/2 is treated as integer arithmetic and as such is rounded to 0.
Removing the parenthesis changes the order of operations, and now you are dividing your whole (floating point) formula by two and arriving at a floating point answer.
That's because 1 and 2 are integer values, not floating point values.
When you divide the integer value 1 by the integer value 2, the result is the integer value 0, not the floating point value 0.5.
When you remove the parentheses and change the order of the multiplication, the other part of the expression will first be multiplied by 1, which will implicitly convert the integer value 1 into a floating point value. Then the result is divided by 2, which will also be implicitly converted into a floating point value.
So what you end up doing is:
value = ( (this.spheres[sphereCount - 1].Theta + this.spheres[sphereCount].Theta) * (float)1 ) / (float)2;