- Home /
How do I perform math on Vector3.x or Vector4.x as if it were a float?
Here is my code. I am trying to extract a single component (Vector3.x) from a Vector3 as a float
g_TCnewpos = Vector4;
g_MC = new Vector4[n];
cForce = Vector3;
var simpleVec4Distance = g_TCnewpos - g_MC[0];
var g_squaredVector = simpleVec4Distance.sqrMagnitude;
// OK so far...
// but then:
cForce.x = (1 / g_squaredVector.x) * g_MC[0].w * g_MC[1].w;
cForce.y = (1 / g_squaredVector.y) * g_MC[0].w * g_MC[1].w;
cForce.z = (1 / g_squaredVector.z) * g_MC[0].w * g_MC[1].w;
generates these ERRORS:
test.js(11,7): BCE0019: 'x' is not a member of 'float'.
test.js(12,7): BCE0019: 'y' is not a member of 'float'.
test.js(13,7): BCE0019: 'z' is not a member of 'float'.
PLEASE HELP, BECAUSE MY HOMEWORK IS DUE!
Answer by Sessional · Dec 05, 2014 at 03:32 PM
Are you sure that g_SquaredVector is actually a vector?
var g_squaredVector = simpleVec4Distance.sqrMagnitude;
In vectors isn't magnitude a single number?
Thats right, magnitude is the sqare root of (x*x + y*y + z*z). So just cut off ".x", ".y", .z" and your homework might be saved ;)
@Lunatix, you're suggesting like this? cForce = (1 / g_squaredVector) g_$$anonymous$$C[0].w g_$$anonymous$$C[1].w;
I thought that sqr$$anonymous$$agnitude, as in Unity docs, is "the squared length of this vector (Read Only). Calculating the squared magnitude ins$$anonymous$$d of the magnitude is much faster" http://docs.unity3d.com/ScriptReference/Vector4-sqr$$anonymous$$agnitude.html
or are you suggesting I change simpleVec4Distance.sqr$$anonymous$$agnitude to simpleVec4Distance.magnitude?
magnitude says "The length of the vector is square root of (x*x+y*y+z*z+w*w)" http://docs.unity3d.com/ScriptReference/Vector4-magnitude.html
I'm trying to calculate the 3d inverse squares (1/x^2) at maximum frame-rate.
@Sessional, I think you're right, sqr$$anonymous$$agnitude is returning a float and not a Vec4. Churning and testing new code based on this...
It says it right there in the docs you linked. sqr$$anonymous$$agnitude returns a single float. So what you are doign is not Vector4.x
but float.x
$$anonymous$$y apologies, @gregroberts, I simply interchanged sqr$$anonymous$$agnitude and magnitude, I just wanted to point out that the sqr$$anonymous$$agnitude is a float but wrote the wrong parameter as an example >_<
Answer by Mosy · Dec 05, 2014 at 04:06 PM
Instead of doing it in separate lines like;
cForce.x = (1 / g_squaredVector.x) * g_MC[0].w * g_MC[1].w;
cForce.y = (1 / g_squaredVector.y) * g_MC[0].w * g_MC[1].w;
cForce.z = (1 / g_squaredVector.z) * g_MC[0].w * g_MC[1].w;
Try doing all of them as one line of code like this;
cForce = new Vector3((1 / g_squaredVector) * g_MC[0].w * g_MC[1].w,
(1 / g_squaredVector) * g_MC[0].w * g_MC[1].w,
(1 / g_squaredVector) * g_MC[0].w * g_MC[1].w);
EDIT It is a best practice in my opinion to change the whole Vector3 at once, instead of each value individually. That should make it slightly faster, as well as ensuring that they don't get edited wrong. If you need to, change the g_squaredVector variable to separate variables to reflect that you wanted each one to be either x, y or z, and hold the correct value.
Really shouldn't down vote without leaving a comment as to what you feel is wrong with the post. Honestly Unity has issues with doing math on Vector3s unless you do them all at once. That could be the problem that you are running into.
@$$anonymous$$osy:
Unity doesn't have issues with math on Vector3s. You might refer to the combination of value type properties like ".position" of the Transform type. This "limitation" has nothing to do with Vector3 specifically. It would happen with any value type (struct) property. In the code here there is no property involved at all.
Your two code examples do exactly the same and since the first doesn't work your second won't work as well. As Sessional and Lunatix said g_squaredVector is not a vector but a float value.
So your answer doesn't answer the question and is misleading.
@Bunny83: I have had problems with Vector3 math outside of structs, so maybe it was just the way it was handled. I did notice that the original code was trying to get the x, y and z values from a float value and took them off. After that, the OP could then tweak the formula as he sees fit to get it to work as he wants it to.
But still down voting without commenting is still not helpful. $$anonymous$$aybe someone just missed something and a comment might help them correct the issue. I come here to help people, and take time out of my own projects to do so. It isn't much to ask that people actually take the time to write a small comment ins$$anonymous$$d of just down voting.
@$$anonymous$$osy: +1 for trying to point out that the change of value types must be done by changing the whole value ins$$anonymous$$d of just a field or parameter, maybe you should alter your answer to point this out.
I fully support your side - a simple comment with a suggestion to alter the parameter g_squaredVector from vector to float in your answer would have been much more efficient than just downvoting.
@Lunatix: Thank you. The fact that the g_squaredVector was a float when it was expected to be a Vector3 is one of the reasons why I hate the usage of var, personally I prefer to explicitly set up my variables as the correct type to prevent errors like that.
Answer by Bunny83 · Dec 05, 2014 at 10:41 PM
It's still not really clear what exactly you want to calculate. As i understand your description you want each component of your Vector3 to be squared and then you want to take the inverse of each component and form a new vector? That sounds really strange to me. What's the purpose of this? It has some similarities with the formula for gravity, however if that's your goal you're way off.
Anyways to square each component of a vector independently from each other you can use the Scale method to scale your vector with itself.
Vector4 g_squaredVector = Vector4.Scale(simpleVec4Distance, simpleVec4Distance);
Now your g_squaredVector would have each component squared (== new Vector4(x*x, y*y, z*z, w*w)).
ps: Your array of Vector4 looks like it should represent a matrix. Unity has the Matrix4x4 type which has all common operators you can do with a 4x4 matrix.
Again, it would help if you would explain your actual problem you want to solve.
edit
Since it looks like you want to calculate the force in an electric field, here's what you have to do. I guess your g_MC array contains your charges of your electric field and each vector is made of a Vector3 that represents the position of a charge and the 4th (w) coordinate is it's charge?
// ...
float k = 8.987551787368e9f; // Coulomb's constant
Vector3 force = Vector3.zero;
foreach(var C in g_MC)
{
Vector3 dir = (Vector3)(g_TCnewpos - C); // only the vector
force += dir.normalized * C.w / dir.sqrMagnitude;
}
force *= k;
Keep in mind that this calculates the force applied to a unit-charge (like in the definition of the electric field). If your "g_TCnewpos" represents a test charge that can have a different charge than 1 you should also multiply by "g_TCnewpos.w". Like this:
force += dir.normalized * g_TCnewpos.w * C.w / dir.sqrMagnitude;
That's it. Of course if you want to calculate the force for simulation purposes you might need to adjust Coulomb's constant or multiply by some scaling factor.
@Bunny83, the purpose of this is to calculate the forces exerted on a test particle by a multitude of fixed charges, and to visualize the resulting beauty.
The equation is called "$$anonymous$$axwell's Law of Electromagnetism". The force exerted on any particle is the inverse square of the distance times the magnitude of the charge. :) I got it solved and thanks for your help.
Here's a peek at my dev :
Ahh, i guess you mean Coulomb's law as $$anonymous$$axwell's equations are more general differential equations.
Coulomb's law is actually the same as Newton's law of universal gravitation just with a different constant (and of course coulomb ins$$anonymous$$d of kilogramm).
If you want to calculate that force you're doing it wrong ;) Take a look at the two formulas on the Coulomb's law page. The first one just calculates the magnitude of the force while the second calculates the force vector. You have to normalize the direction vector and just scale it with the magnitude of the calculated force.
I'll add this to my answer.