Archived

This topic is now archived and is closed to further replies.

Sander

My vectors won't wobble

Recommended Posts

Sander    1332
I'm creating a particle system lib and now I want to make a Rocket engine particle system. I need a somewhat cone-shaped distribution. After some forum searches I read about using polar coords and applying a random component to the latitude and longtitude. I tried the method outliden in the Vector FAQ (section of the matrix and quaternion FAQ) the results are not what I expect them to be. I created a vWobble(...) function that takes a vector and an angle and returns a new vector that lies within the cone described by the original vector and the angle. The first thing that goes wrong is that it rotates the vector 90 degrees for some reason. The initial vector given points to the left (-0.01f, 0.0f, 0.0f). However, I get this (Y points up): The next thing (I expected) to go wrong was that the cross-section of the shape would be square instead of circular. However, I get a line! Here's a screenshot viewed from the top: Can anyone tell me what is going wrong? I'm afraid my math isn't sufficient to figure this one out on my own. Here's the vWobble code.
//randomly rotate the vector over angle degrees

//this is going to be slow!

inline float3 vWobble(const float3 &a, int angle)
{
	float angle1, angle2;
	float3 norm, temp, result;

	//generate two random angles (tens of degrees) between -halfangle and halfangle

	angle1 = ((rand()%(angle*10)/10.0f)-(angle/2.0f))*(3.14f/180.0f);
	angle2 = ((rand()%(angle*10)/10.0f)-(angle/2.0f))*(3.14f/180.0f);

	//convert euclidean coords to polar coords. x=latitude, y=longtitude, z=distance

	norm=a; //removed normalization step as given by the Matrix FAQ.

	temp.z=fastSqrt(norm.x*norm.x + norm.z*norm.z);
	temp.x=atan2(temp.z, norm.y);
	temp.y=atan2(norm.x, norm.z);

	//add random components

	temp.x+=angle1;
	temp.y+=angle2;

	//convert polar back to euclidean

	result.x=cos(temp.x)*sin(temp.y)*temp.z;
	result.y=sin(temp.x)*temp.z;
	result.z=cos(temp.x)*cos(temp.y)*temp.z;

	return (result);
}
Thanks a lot in advance! Sander Maréchal [Lone Wolves Game Development][RoboBlast][Articles][GD Emporium][Webdesign][E-mail] [edited by - sander on September 1, 2003 1:58:20 PM]

Share this post


Link to post
Share on other sites
Nik02    4348
One obvious bug:

replace this...
result.z=cos(temp.x)*cos(temp.y)*temp.z;

with this:
result.z= -sin(temp.x)*cos(temp.y)*temp.z;

[edited by - Nik02 on September 1, 2003 2:03:58 PM]

Share this post


Link to post
Share on other sites
Sander    1332
Wow, that was fast

It fixes the problem that the particles all lie in the same plane, but the cross section is still square (I''d really prefer circular. I don''t know of any rocket engine''s giving of square smoke). Screenshot:


Also, the returned vectors are still pointing roughly up (in the positive Y direction) whereas I specify the original vector to go in the X+ direction.

Sander Maréchal
[Lone Wolves Game Development][RoboBlast][Articles][GD Emporium][Webdesign][E-mail]

Share this post


Link to post
Share on other sites
Nik02    4348
I think you feed the atans the wrong components.

EDIT:
More specifically, in wrong order.

Sorry, i'm sleepy, if you're having trouble tomorrow with this, i'll get back to you.

rgds Nik

[edited by - Nik02 on September 1, 2003 2:45:41 PM]

Share this post


Link to post
Share on other sites
Nik02    4348
Also, try to multiply the output vec's components with reciprocal of the square root of norm.x2+norm.z2 instead of the root itself.

EDIT:
Removed potential confusion between exponents and c XOR operator.

[edited by - Nik02 on September 1, 2003 3:08:53 PM]

Share this post


Link to post
Share on other sites
Cedric    158
I'm not sure about the problem with your math, but generating a random distribution has been discussed very often, and the best solution is generally to generate random points in a box, and take only the ones that are inside the cone.

The test would be very easy to do; all you have to do is to check if the distance between the point and the line in the middle of the cone is less than kz, where k is the slope of the cone.

Plus, you would get a uniform distribution, which is always easier to manipulate than a non-uniform one.

Cédric

EDIT: Softer, nicer, better.

[edited by - Cedric on September 1, 2003 3:28:52 PM]

Share this post


Link to post
Share on other sites
Andos    124
Or just create the particles a random place in it.
If you have the middle line in the cone you could create the particles at:

Z= Random( ConeHeight )+ ConeZpos
X= Sin( random(6.28) )* (z*something) + ConeXpos
Y= Cos( random(6.28) )* (z*something) + ConeYpos

Share this post


Link to post
Share on other sites
Sander    1332
I found some other method that gives me a pretty good distribution. I create a random vector and cross it with the velocity vector. I use this vector to push the particles away from the rocket trajectory. I can now even get a paraboloid shaped cone near the engine which spreads out to form a straight column of smoke further away by decreasing this vector every timestep. Looks pretty good IMHO


Sander Maréchal
[Lone Wolves Game Development][RoboBlast][Articles][GD Emporium][Webdesign][E-mail]

Share this post


Link to post
Share on other sites