My vectors won't wobble

Started by
6 comments, last by Sander 20 years, 7 months ago
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]

<hr />
Sander Marechal<small>[Lone Wolves][Hearts for GNOME][E-mail][Forum FAQ]</small>

Advertisement
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]

Niko Suni

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]

<hr />
Sander Marechal<small>[Lone Wolves][Hearts for GNOME][E-mail][Forum FAQ]</small>

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]

Niko Suni

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]

Niko Suni

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]
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
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]

<hr />
Sander Marechal<small>[Lone Wolves][Hearts for GNOME][E-mail][Forum FAQ]</small>

This topic is closed to new replies.

Advertisement