Closed ghost closed 4 years ago
You are creating a plane that contains 3 specified locations.
The plane is defined as a point and normal vector.
The normal of the vector ends up being:
n = ((6, 0, 10) - (0, 0, 10)) cross ((3, 4, 10) - (0, 0, 10))
= (6, 0, 0) cross (3, 4, 0)
= (0, 0, 24)
When normalized, this becomes:
n = n / n.length
= (0, 0, 24) / sqrt((0 * 0) + (0 * 0) + (24 * 24))
= (0, 0, 24) / sqrt(0 + 0 + 576)
= (0, 0, 24) / sqrt(576)
= (0, 0, 24) / 24
= (0, 0, 1)
d
is then defined as:
d = -((0, 0, 1) dot (6, 0, 10))
= -((0 * 6) + (0 * 0) + (1 * 10))
= -(0 + 0 + 10)
= -10
As stated on the other thread, many of these types require some knowledge of linear algebra to understand correctly.
All of the behaviors are (to my knowledge) following the standard rules for defining the corresponding geometric type.
@tannergooding If you look at the tanh method documentation here: https://msdn.microsoft.com/en-us/library/system.math.tanh(v=vs.110).aspx You will see these notes:
Return Value Type: System.Double The hyperbolic tangent of value. If value is equal to NegativeInfinity, this method returns -1. If value is equal to PositiveInfinity, this method returns 1. If value is equal to NaN, this method returns NaN. Remarks The angle, value, must be in radians. Multiply by Math.PI/180 to convert degrees to radians
Writing important remarks about input and output values is familiar in. Net documents. Negative space is unusual thing and can cause unexpected results if used in other calculations. A note about the sign related to where the point resides from the plane can save a lot of time. You can find others asking about this sign in other forums.
If you look at the tanh method documentation here:
The tanh
documentation is describing the behavior for special inputs which may behave differently or which are handled specifically due to the underlying format of the float
and double
types (which are the IEEE 754 binary32
and binary64
types, respectively).
Negative space is unusual thing and can cause unexpected results if used in other calculations.
Negative coordinates are not unusual. In Euclidean space, when using a Cartesian Coordinate system:
All of the trigonometric functions, which you mentioned the documentation on, deal with both positive and negative coordinates. Yet the documentation makes no mention of that, because you are expected to have a basic understanding of the functions already. The documentation only explicitly lists the special cases.
Also, to be clear, I am not saying that the documentation couldn't be improved. It definitely could be more explicit stating that these are Euclidean types and operating in a Cartesian coordinate system (I believe some of our functions assume a Right-Handed system, but I don't recall off the top of my head).
However, going in depth in the underlying mathematics behind the functions is clearly out of scope (IMO).
CC. @eerhardt
A distance is an absolute value resulting from the difference betwwn two points in the coordinates. D in my example resides in the positive side of the z axes. The confusion comes from using the origin point in calculating D, so there are two references: the oeriginal axis and the plane surface!.. This is unusual! Negative distance seems like a quantum mechanics concept or something. Anyway, a small hint wouldn't heart.
A distance is an absolute value resulting from the difference betwwn two points in the coordinates.
I think a more accurate description might be: A distance, when no direction is provided, is an absolute value resulting from the difference between two points in the coordinates.
Think of it like this:
D
D
In the example you provided, we are facing (0, 0, 1)
and we moved 10
steps backwards. What you see when looking forward and moving 10 steps backwards is completely different from what you see if you turn around and move 10 steps forward, even though you ultimately start and end at the same locations.
@tannergooding There is another confusion: If the sign of D is -ve if the point (which is the origin here) resides on the opposite side of the normal vector, so why the Z = -10 plane has (D = 10) in this example, while the origin is also at the opposite side of its normal vector?
var P = Plane.CreateFromVertices(
new Vector3(0, 0, -10),
new Vector3(6, 0, -10),
new Vector3(3, 4, -10));
Console.WriteLine(P.D);
What is the concept used here? How can I know the right sign when I send the distance to the Plane's constructor?.. Why can't I send an absolute value? This ambiguity can produce undesired results.
The normals of the two planes are different and face in opposite directions:
Yes, and this makes the origin resides on the -ve face of each planes, so it should be a -ve destsnce as I understand! Do I miss something here?
I tested the two cases. The Normal of the two planes, as given by P.Normal property, is: <0, 0, 1> This is the reason of the sign of D in each case. But, Why are the two planes have the same normal vector? This is why I keep asking the implementors about the start and end points of the vector!
I'm not comfortable with the implementation of the vector as a single point. In Plane.CreateFromVertices method, Vector3 parameters are treated as points!! I would prefer to define a vector with start and end points and have properties or methods to calculate angles. If you have a vector AB not passing through the origin, you will have to do some calculations to find the correct point to define Vector2 ar vector3 in current implementaion! Or at least add a constructor to Vector structures thar accepts two points, so the subtraction of the two points to get the vectors end point can be optimized as SIMD operations.
Vectors should be more easier, realistic. and less confusing.
This is exactly how many other libraries have been doing all of this for years:
I don't believe our implementation is any less correct or more confusing than any other major vector math library in production use today.
In Plane.CreateFromVertices method, Vector3 parameters are treated as points
Yes. This is also a common practice in these types of libraries. A 3-dimensional vector and a 3-dimensional point each have the same properties, functions, etc. The primary difference between the two is what you call it and whether you treat the data as a point or a vector.
@tannergooding Thanks, but I'm still confused. What is the defense between these 2 planes: var P1 = new Plane(0, 0, 1, 10); var P2 = new Plane(0, 0, -1, -10); P1 == P2 returns false also, what is the defense between these 2 planes: var P3 = new Plane(0, 0, 1, -10); var P4 = new Plane(0, 0, -1, 10); P3 == P4 returns false
I tested other equalities. I found that P1, P2, P3 and P4 are considered 4 deferent planes! I can only imagine two of them, so what are the other two? Do you feel that the -ve distance have a useful meaning?
@MohammadHamdyGhanem You can imagine only 2 because you don't consider that plane facing opposite direction is not the same plane
But facing is a property that could be used in some logic. So it is a difference plane
Think about integrate, there was an "signed area under the curve" and facing side is matter
@MohammadHamdyGhanem You should learn math before do programming.
@ufcpp Don't be so harsh. I think this is just a problem of concept and definition. In some sense plane facing opposite direction could theoretically be considered as a same plane. It just definition in math library is not
Anyway @MohammadHamdyGhanem actually you should not and could not compare float and product of floats calculation with ==
@Thaina
actually you should not and could not compare float and product of floats calculation with ==
If you refer to decimal accuracy problem, I think the Equality Operator of the Plane Structure should handle it. But when I looked at source code, it seems not!
public static bool operator ==(Plane value1, Plane value2)
{
return (value1.Normal.X == value2.Normal.X &&
value1.Normal.Y == value2.Normal.Y &&
value1.Normal.Z == value2.Normal.Z &&
value1.D == value2.D);
}
So, can we trust the equality operations of the SIMD-Enabled types?
@MohammadHamdyGhanem You cannot rely on equality operator anywhere in float operation. It does what the float does for equality. And it trustable that it would not be equal if the float came out with the same inequality for precision error
In fact it logically correct for equality function to not try to approximate precision error. Which is why you should not use it after any operation. Same go for every Math and Numerics struct related to float. That was the reason we have Vector3.Distance(l,r)
function
The most logical reason is, we don't really know what each people and each application would consider how large the precision error would be acceptable
@Thaina Thanks for the warning :) I examind the sample of the CreateFromVertices. Changing the 3 points order changes the Normal direction an D sign. It seems there is some right-hand or left-hand rule.
var P1 = Plane.CreateFromVertices(new Vector3(0, 0, 10),
new Vector3(3, 4, 10), new Vector3(6, 0, 10));
MessageBox.Show(P1.Normal.ToString()); // <0, 0, -1>
MessageBox.Show(P1.D.ToString()); // 10
var P2 = Plane.CreateFromVertices(new Vector3(0, 0, 10),
new Vector3(6, 0, 10), new Vector3(3, 4, 10));
MessageBox.Show(P2.Normal.ToString()); // <0, 0, 1>
MessageBox.Show(P2.D.ToString()); // -10
This deserves a warning not in documentaions, beacuse the same three points can give two different planes, just by changing the order you write them! Thanks.
This deserves a warning not in documentaions
Agreed that the documentation could be updated for these types of things. As per my comment above (https://github.com/dotnet/corefx/issues/26497#issuecomment-359273640), we could definitely be more explicit about which coordinate space we are operating in and when the ordering of parameters matters.
beacuse the same three points can give two different planes, just by changing the order you write them!
This is standard behavior for this algorithm because the normal is defined as (p2 - p1) cross (p3 - p1)
(https://github.com/dotnet/corefx/issues/26497#issuecomment-359267925)
@eerhardt, I think we should see if we can reuse the existing DirectX Math documentation, where applicable.
If the normal vector (a, b, c) is normalized, then the plane equation is: ax + by + cz + D = 0 By the way, this equation is mentioned in DirectX documents. It is important to put this equation in the documents of the Plane constructor. Now it is clear why D has a sign, and why the field is called D not Distance. It is a coefficient not just the absolute distance. May be things be less confusing if you added a Distance property besides the D field. This equation give meaning to some plane methods like Plane.DotCoordinate which can be used to determine if a point belongs to the plane (if it returns 0). The problem with this method is that plane must have a normalized normal vector to give the desired result, but the plane can be constructed with a vector that is not normalized! Maybe Plane.Normal should always return the normalized normal vector. another problem of cource is that it may not return 0 because single. I think adding such notes to documentation would make programmers life happier. Programmers don't care about math. They want a method to determine if a point is on the plane surface or not, to detect a collision or something. Maybe it's better to add a Plane.ContainsPoint method and make sure to avoid the single round problem. Maybe something like this:```
public bool ContainsPoint(Vector3 point)
{
var n = this.Normal;
if( n.Length != 1)
n = Vector3.Normalize(n);
return Math.Round(Vector3.Dot(point, n) + this.D) == 0;
}
@MohammadHamdyGhanem First thing first, NO. Programmers do care about math and they need to do. They must do. Programmer must care about math. In fact humanity should care about math
Even if/else is a math. It is boolean algebra
Second. Statistically, given arbitrary point and plane there would be ZERO chance that the point would be on the plane Hypothetical plane is infinitesimal thin. A random point will have infinitesimal chance to land on it. Mathematically way to do a point-on-plane checking is not to make an equation but using inequation to have it as near as the acceptable range, which, as I said, it varied between application. Astronomical application would accept range in Earth's diameter, and quantum mechanic application would accept range less than Planck's length
Third. It might be counter intuitive but having normal vector not normalized is applicable in case we want the product that scale. Plane with a size is like tensor field. It could encode not only direction but also tension. And calculate with it give you the scaled distance relative to the plane. Its about relativity. So it was more useful to leave all math function as plain as it is and programmer is responsible to normalize it if it need to, even if it is the most case, but it not leave the edge case be impossible
Lastly, all in all, everything I said is came from math and this proven that programming is math and programmer need to care about math. Go learn math. We need to learn math and we should learn math for whole life. We can learn math until we die
@Thaina You seem as a math fan :) I speak from RAD point of view. You love math, so put it in a good liberrary for us :).. Computers are invented to do the math. Let it do. Chicking a point on a plain is not that random. A plane is infinit surface that splits space into halfs. Any moving object will hit it eventually. Checking a point was just an example. Getting intersection point with a vector, ijntersection line with another plane, and defining areas are good things to do.
leave all math function as plain as it is
This is why I wrot the ContainsPoint function thst normalizes the normal vector first.
thanks.
@MohammadHamdyGhanem I became a math fan AFTER I became programmer and knowing that programming, in fact computing, IS ALL about Math. It's unavoidable to love math as being programmer or else you can't go anywhere
Everything about research and development is also math
Computer made for computing, doing calculation. But that's not Math. Math is how to compute. You need to learn the difference between "doing calculation" and "doing equation to calculate", in short you need to learn math
You write equation for computer, computer don't write thing for you. You using library is SOMEONE help write it for you, not a Computer. No computer write equation for you unless there are AI that clever than human. Which is not exist yet
A plane is infinit surface that splits space into halfs. Any moving object will hit it eventually
This is why you need to learn math. There was infinite number of trajectory parallel to the plane in one more dimension than the infinite trajectory on the plane. If you take limit you will get zero
And if you talk about moving then mathematically that point is not a point but a line segment in four dimension. So the line-plane intersection would be another equation, not a point-plane distance equation
This is why you need to learn math as being programmer
@Thaina I have already learned math in fuculty of engineering before becoming a programner. I know probability as will. Math From an engineer's point of view is practical not theoretical. Each point we deal with exists on some surface. When you represent a plane in programming or physical problem you have some boundary conditions. In games things can have a random motion that can't be represented with a line or a curve. What you do if you want to check if the next move hits one of boundary planes? Anywsy, this is not our concern here. Plane equation exists to tell us about each point, line and area on this plane, which indicats intersections with other objects. I say it will be nice if Plane structure do these calculations for us. Yes of cource, a brilliant math programmer should do it for poor programmers like me :) Thanks for this good discussion.
@MohammadHamdyGhanem In game programming we need to do sweep test in time dimension, which is as I said it would be line-plane intersection. You have the point of previous frame and point on current frame so it is line segment
Plane equation exists along with inequation which is the similar formula. You trying to use equation where you need inequation is flawed logic. No need to account precision error, just statistical, it not practical to do equality test with point which has no size
It like a math problem that ask, what is a chance to land a dart on the center of dart board, and answer is zero
That's what theoretical math could told you. It can tell you what really practical and what really impossible
I think the questions have been answered, and this issue can be closed. Please re-open if I am incorrect.
If this is not a bug, at least it is a good example showing why I keep asking the implementers about their conventions and why not putting them in the documentation:
D is -10. Why? This is the Z = 10 plane, so where the negative sign came from? Documents says:
This should give a positive distance ! Above all, distance should be an absolute value, because the normal vector holds the direction.
EDIT: In this example, the normal vectors for the planes P1 and P2 are identical, although the two planes are parallel and in oposite directions of the Z axis.
This indicates that the origin is not always the start point of the vector, which is strang and confusing! What is the rule used here if this is not a bug? It is always a good thing to state the basic conventions in documents. At least we can report bugs when we know they are bugs!!
EDIT: D shounldn't be refered to as "the distance in documentation". Distance is a scaler value that is always positive. Abs(D) is the distance! If the normal vector (a, b, c) is normalized, then the plane equation is: ax + by + cz + D = 0 By the way, this equation is mentioned in DirectX documents. It is important to put this equation in the documents of the Plane constructor. Now it is clear why D has a sign, and why the field is called D not Distance. It is a coefficient not just the absolute distance. May be things be less confusing if you added a Distance property besides the D field. This equation give meaning to some plane methods like Plane.DotCoordinate which can be used to determine if a point belongs to the plane (if it returns 0). The problem with this method is that plane must have a normalized normal vector to give the desired result, but the plane can be constructed with a vector that is not normalized! Maybe Plane.Normal should always return the normalized normal vector. another problem of cource is that it may not return 0 because single. I think adding such notes to documentation would make programmers life happier. Programmers don't care about math. They want a method to determine if a point is on the plane surface or not, to detect a collision or something. Maybe it's better to add a Plane.ContainsPoint method and make sure to avoid the single round problem. Maybe something like this: