I have two Vector3, that each represent the size of an area. First one is the total amount of the area. Second one is just a part of the first one. How do i get the percentage, that remains of the total area, when i subtract the smaller area?
If both represents size (they are positive in components by definition) and fully interesects (one fully lies in borders of another), then you just need to calculate percentage of their volume difference:
|v1.volume - v2.volume|/max(v1.volume, v2.volume)
So in code it will look like this:
double v1Volume = v1.x * v1.y * v1.z;
double v2Volume = v2.x * v2.y * v2.z;
double percentageDiff = 100 * Math.Abs(v1Volume - v2Volume) / Math.Max(v1Volume, v2Volume);
This way, it doesn't even matter which one small and which one big, just put both in this function and it will show correct answer.
I'm loading coordinate values with GraphichsPath.AddLine command, then drawing them and I've noticed my map is not quite accurate.
The code in question is as follows. I'm casting start and end coordinates from double to float since the command takes only float values, then multiplying them so they scale better:
GraphicsPath gp = new GraphicsPath();
gp.AddLine((float)(line.startX*10000), (float)(line.startY * 10000),
(float)(line.endX * 10000), (float)(line.endY * 10000));
For example, startX value is 15.742560625076294 but when i check the gp path data in debugger, I see it as 157425.609. The last 7 digits are shortened. And they are crucial because the difference in meters is important in this case.
Is this the limitation of a float value as opposed to double? How can I load the full values in said command?
I am baffled by this one.
So I have a console application doing a lot of calculations (trust me, thousands of them ). In one method, I have some parameters that need calculating, in different situations. For one of them, the mathematical expression is basically the same, only one difference in a term. Here is the code snippet along with all the lines between the 2 formulas in question, the Nq1 and Nq2 ones ( first formula of the code and last one to be more easy ):
//drained conditions
Nq1 = Math.Round((Math.Pow(Math.E, Math.PI * Math.Tan(studiu.Fi * Constants.ConversionToDeg)) * Math.Pow((Math.Tan(45 + studiu.Fi / 2.00) * Constants.ConversionToDeg), 2)), 2);
//Combination 2
studiu.Fi = FiAfectat;
//drained conditions
Nq2 = Math.Round((Math.Pow(Math.E, Math.PI * Math.Tan(studiu.Fi * Constants.ConversionToDeg)) * Math.Pow((Math.Tan(45 + studiu.Fi / 2.00) * Constants.ConversionToDeg), 2)), 2);
The first formula returns 18.04 but the second one returns 0.01. How is this possible ? Only the studiu.Fi term differs, but not by that much ( 32 in the first case and 27 in the second ).
How can Nq1 be 18 and Nq2 be 0.01 ? Am I missing something here ?
Tan(x) is a periodic function that will change drastically for a small change in x. Since the two formulas only differ by a term inside the Tan function, this is likely your problem.
Also, it is likely that you should be using radians instead of degrees. If this is the case you should use a command that converts real numbers to radians instead of one that converts to degrees.
I need to convert any range to a -1 to 1 scale. I have multiple ranges that I am using and therefore need this equation to be dynamic. Below is my current equation. It works great for ranges where 0 is the centerpoint. I.E. 200 to -200. I have another range however that isn't converting nicely. 6000 to 4000. I've also tested 0 to 360 and it works.
var offset = -1 + ((2 / yMax) * (point.Y));
One of the major issues that I may have is that sometimes I'll get a value that is outside the range, and as such, the converted value needs to also be outside the -1 to 1 range.
What this is for is to take a value that is a real world value, and I need to be able to plot it into an OpenGL point. I'm using .NET 4.0 and the Tao Framework.
rescaled = -1 + 2 * (point.Y - yMin) / (yMax - yMin);
However, in OpenGL you can do this with a projection matrix (or matrix multiply inside a shader). Read about glTranslatef and glScalef for how to use them or how to duplicate them with matrix multiply.
If tan(x) = y and atan(y) = x why Math.Atan(Math.Tan(x)) != x?
I´m trying to calculate x in something like:
tan(2/x +3) = 5
so
atan(tan(2/x + 3) = atan(5)
and so on... but I´ve tried this:
double d = Math.Atan(Math.Tan(10));
and d != 10. Why?
The tangent function is periodic with period pi, and is invertible only if you restrict it to a subset of its domain over which it is injective. Usually the choice of such set is the open interval ]-pi/2, pi/2[, hence the arctan function will always return a point in that interval. In your case, 10 = 3*pi + 0.57522... Thus, the arctan of the tangent of 10 will return 0.57522...
Note that the arctan function, defined as above, is injective and defined over all the real numbers, hence the converse of your problem math.tan(math.atan(x)) == x
indeed holds for each x (except for numerical errors).
In order to deal with numerical errors, you should never perform comparisons between the results of floating point computations using == or !=. Use abs(number1 - number2) < epsilon // ==
abs(number1 - number2) >= epsilon // !=
instead, where epsilon is a small positive constant.
A graph might help explain why you are not getting the result you expected.
(source: wolfram.com)
http://mathworld.wolfram.com/Tangent.html
That shows the graph of Tan, but if you imagine reading off a value of x for a given y, (e.g. y = 0) then depending on which "strand" of Tan you read, you will get a different answer (-pi, 0, pi...). That's the point about Arctan(x) having more than one solution.
If arctan was restricted to only one of those strands, e.g. -pi/2 < x < pi/2 then Arctan(tan(x)) will return x providing you have accounted for floating point errors.
EDIT: However, according to http://msdn.microsoft.com/en-us/library/system.math.atan.aspx, the atan method already returns -pi/2 < x < pi/2 or NaN if your input is undefined. So the problem must soley be down to floating point rounding.
EDIT (F.R.): Added figure
I dont know any C#, but maths says that tan is not invertable, only in a small intervall.
e.g. tan(pi) = 0 and tan(0) = 0. When asking for atan(0) it could be 0 or pi (or every multiple of pi), so the result is in the range from -pi/2 .. pi/2.
Even if you start with an x in the invertable range i doesnt has to work, because of rounding errors with the floating points (it has not unlimmited precision).
tan-1(tan(x)) == x for all x in (-PI/2, PI/2).
Because the tangent function is periodic we need to normalize input angle. Math.Atan returns an angle, θ, measured in radians, such that -π/2 ≤ θ ≤ π/2, so it makes sense to normalize to that range (since it obviously won't anything within that range anyway):
double normalizedAngle = (angle + Math.PI / 2) % Math.PI - Math.PI / 2;
Doubles should be compared with some error margin. But in fact for this case Double.Epsilon is too small and "If you create a custom algorithm that determines whether two floating-point numbers can be considered equal, you must use a value that is greater than the Epsilon constant to establish the acceptable absolute margin of difference for the two values to be considered equal. (Typically, that margin of difference is many times greater than Epsilon.)" For instance, Math.Atan(Math.Tan(-0.49999632679501449)) + 0.49999632679501449 will be greater than Double.Epsilon for 1.1235582092889474E+307 times.
It might be helpful if you posted what you are trying to accomplish. I have recollections of discovering trig functions that handled the issue if what quadrant the inputs were in for me when I tried playing with angles, for example.
In general, when you are dealing with floating point numbers, you are dealing with approximations. There are numbers that cannot be represented exactly, and the tan and arctan operations are themselves only approximate.
If you want to compare floating point numbers, you need to ask if they are nearly equal, or equivalently, if the difference is less than some small value, and think carefully what you are doing.
Here is are some FAQS (for c++, but the idea is the same), that talk a bit about some of the oddities of floating point numbers:
FAQ 29.16
FAQ 29.17
FAQ 29.18
Edit: Looking at the other answers, I realise that the main problem is probably that tan isn't invertible, but the approximation issue is worth considering too, whenever you test floating point numbers for equality.
Looking at the .net documentation for Math.Atan, atan produces a value between -π/2 and ≤ π/2, which doesn't include 10. That I think is the usual range for arctan.
double d = Math.Atan(1) * (180 / Math.PI);
so d will be 45 in degrees