Advertisement

Getting circle quarter based on Vector3 direction

Started by May 18, 2013 11:31 AM
22 comments, last by Medo Mex 11 years, 9 months ago

I'm trying to get quarter of the circle based on a certain direction (velocity)

The number that I want should be between -D3DX_PI and D3DX_PI, How do I determine it based on the velocity direction?

Example:

Lets say I have the velocity of: (X: 0, Y: 10, Z: 0), in this case the velocity is pointing at the upper direction, so the numbers between -D3DX_PI and D3DX_PI that I should get are based on the upper quarter of the circle.

So, I want to determine which quarter of the circle the velocity is pointing at.

Your question is very confusing.

Reading between the lines it sounds like maybe you want to extract heading (aka yaw) and elevation (aka pitch) values from your direction vector.

Rather than deriving them I google "direction vector to euler angles" and landed on this gamedev post: http://www.gamedev.net/topic/399701-convert-vector-to-euler-cardan-angles/

Which contained the following snippet (which I modified seeing as in your case Y is up):

"A direction vector can be turned into a pitch and yaw (two Euler angles) thusly:


double yaw = Math.Atan2(ds.X, ds.Z);
double pitch = Math.Atan2(ds.Y, Math.Sqrt((ds.X * ds.X) + (ds.Z * ds.Z)));"
Advertisement

Reading between the lines it sounds like maybe you want to extract heading (aka yaw) and elevation (aka pitch) values from your direction vector.


If your reading is correct, I would say heading is "longitude" and elevation is "latitude", and what he needs is a conversion from Cartesian to spherical coordinates. That happens to have the exact same equations you posted.

Let me make it more clear

I have this function:


D3DXVECTOR3 GetRandomVector(D3DXVECTOR3 velocity)
{
    D3DXVECTOR3 vVector;

    // Pick a random Z between -1.0f and 1.0f.
    vVector.z = GetRandMinMax( -1.0f, 1.0f );

    // Get radius of this circle
    float radius = (float)sqrt(1 - vVector.z * vVector.z);

    // Pick a random point on a circle.
    float t = GetRandMinMax( -D3DX_PI, D3DX_PI ); // I THINK THIS LINE SHOULD BE MODIFIED TO PICK A POINT LIMITED TO QUARTER OF THE CIRCLE (According to the direction of D3DXVECTOR3 velocity)

    // Compute matching X and Y for our Z.
    vVector.x = (float)cosf(t) * radius;
    vVector.y = (float)sinf(t) * radius;

    return vVector;
}

In the above method, the random vector is anywhere on the circle between (-D3DX_PI, D3DX_PI) I want to limit the random number to be only quarter of the circle based on the direction of D3DXVECTOR3 velocity.

Define "quarter of the circle". Is that based on standard quadrants (0..90, 90..180, 180..270 and 270..0) picking the one said vector is located in, or is it a cone of some given width centered on the vector? (and if the latter, what width? and what distribution?)

“If I understand the standard right it is legal and safe to do this but the resulting value could be anything.”

If I give a velocity of (0, 10, 0) I want to get A and B accordingly.

0, 10, 0 direction is UP so the result should be the upper quarter.

[attachment=15796:circle.png]

I should change the following line:


float t = GetRandMinMax( -D3DX_PI, D3DX_PI );

To:


float t = GetRandMinMax( A, B );

How do I calculate A and B based on the velocity (direction)?

Advertisement

So a quarter centered on the velocity vector. In that case, you need to get the angle the vector is pointing towards (the above answers answer this part, depending on which axis you want the quarter circle in), call it theta. From your code, it seems you want the angle in the XY plane, so theta = atan2(velocity.y, velocity.x). Once you have this angle, you just go:


float t = GetRandMinMax(theta - D3DX_PI / 4, theta + D3DX_PI / 4)
 

That is, from theta - 45 degrees to theta + 45 degrees. As you can see, you get a random angle within the desired quarter, and can create a new vector with it.

That said, you seem to be creating a random 3D vector. In this case, would it not be better to choose the cone centered on the velocity vector rather than the quarter circle? I'm afraid with the above modification, you won't get the effect I think you are looking for.

“If I understand the standard right it is legal and safe to do this but the resulting value could be anything.”

I'm trying to create random vector that points at the velocity (for particles)

So I have:

D3DXVECTOR3 velocity;

float velocity_var;

According to the above variables I want to make the particles generate to move according to the "velocity", however, velocity_var should determine how much the particles will spread.

Example 1:

Velocity: 0.0f, 10.0f, 0.0f

velocity_var: 4.0f

End Point

\ /

\ /

\ /

\ /

Start

Example 2:

Velocity: 0.0f, 10.0f, 0.0f

velocity_var: 0.0f

End Point

|

|

|

|

Start

The above works perfectly, however, since my particles are lines, the lines are not pointed at the velocity when generated and that's what I'm trying to fix.

Can you provide a little bit of code so I can understand you better?

Here is how I generate a new particle:


void generateNewParticle()
{
      // ...
      D3DXVECTOR3 randVec = GetRandomVector();
      particle.velocity += randVec * velocity_var;
      particle.position = particle.velocity;
      // Code to add the particle to the list here...
}

D3DXVECTOR3 GetRandomVector()
{
    D3DXVECTOR3 vVector;

    // Pick a random Z between -1.0f and 1.0f.
    vVector.z = GetRandMinMax( -1.0f, 1.0f );

    // Get radius of this circle
    float radius = (float)sqrt(1 - vVector.z * vVector.z);

    // Pick a random point on a circle.
    float t = GetRandMinMax( -D3DX_PI, D3DX_PI );

    // Compute matching X and Y for our Z.
    vVector.x = (float)cosf(t) * radius;
    vVector.y = (float)sinf(t) * radius;

    return vVector;
}

Here is how I draw the sparks every frame:


RenderSingleLine( particle.position, particle.position - particle.velocity * lineLength );

I'm not really good in mathematics.

Now, I'm trying to change the code to make the spark lines look at the moving direction instantly after they get generated.

The variable "axis" is not defined.

Do you mean the velocity?

I tried giving axis a value of (0, 10, 0) to make the particles move up, but they still start looking down then moving up.

This topic is closed to new replies.

Advertisement