Page 1 of 2 12 LastLast
Results 1 to 10 of 12

Thread: Random Vectors problem solved

  1. #1
    Senior Member OpenGL Guru
    Join Date
    Dec 2000
    Location
    Reutlingen, Germany
    Posts
    2,042

    Random Vectors problem solved

    Hi guys, some days ago, i asked, if someone knows, how to produce a random vector around a "normal". I didnīt get so much replies, maybe because it is hard to explain.
    However, thanks to my math-teacher, i solved the problem now, and i think, it would be interessting for all those people, who think of the same problem, because it can be very usefull in particle-systems.
    So hereīs the solution (quite long):

    VECTOR RandomVector (VECTOR Normal, int iMaxAlpha, float iDesiredLength)
    {
    /* THEORY
    We want to produce a vector, which points in the direction of "Normal"
    but has a deviation of maximal "iMaxAlpha" into any direction.

    To produce a random vector, we take a vector parallel to the x-axis (1,0,0)
    and rotate it first around the z-axis. If we did this by 45 degree, we would
    for example get (0.7, 0.7, 0)
    Then we rotate it around the x-axis by a random angle between 0 and 360 degree.
    For example, if we did this by 90 degree, we would get (0.7, 0, 0.7).

    Then we have a random vector around the x-axis. To get it to be a vector around
    "Normal", we have to rotate it around two axis by the angle between "Normal" and
    the used axis.

    Thats all

    To do this, you need a simple 3x3 matrix class and a vector class. And you
    need a function, to multiply the matrix with the vector.

    Because you need sin and cos very often, you may precalculate the values and
    store them in an array, just as i did. (Therefore i shorten the float-angles
    to int-angles.)

    Hope, you may find it usefull.
    */

    //calculate the length of "Normal" in the XY-plane
    float lengthxy = Normal.x*Normal.x + Normal.y*Normal.y; // sqared length
    lengthxy = sqrt (lengthxy); // real length

    //calculate the angle between the x-axis and "Normal" in the XY-plane
    float alphaxy = Normal.y / lengthxy; // sin alpha = y / hypotenuse
    int ialphaxy = (int) (asin (alphaxy)*180.0f/3.141f);//convert it to degree

    //calculate the length of "Normal" in the XZ-plane
    float lengthxz = Normal.x*Normal.x + Normal.z*Normal.z; // sqared length
    lengthxz = sqrt (lengthxz); // real length

    //calculate the angle between the x-axis and "Normal" in the XZ-plane
    float alphaxz = Normal.z / lengthxz; // sin alpha = z / hypotenuse
    int ialphaxz = (int) (asin (alphaxz)*180.0f/3.141f);//convert it to degree


    //now we take a vector, which is parallel to the x-axis and rotate it to create a
    //random vector

    VECTOR n (1,0,0);//x-axis

    int alpha = rand () % iMaxAlpha;//we will rotate it by alpha around the z-axis

    //here comes our matrix, which will rotate the vector around the z-axis
    MATRIX3X3 mat (COS[alpha], -SIN[alpha], 0,
    SIN[alpha], COS[alpha], 0,
    0 , 0 , 1);


    //we multiply mat and n (matrix multiplication), to rotate n and store it in d
    VECTOR d = mat * n;

    //our new vector lies in the XY-plane (because we rotated it around the z-axis),
    //now we rotate it around the x-axis, so it will lie in all three planes
    int beta = rand () % 360; // rotation around x-axis

    //here comes our rotation matrix
    mat.SetMatrix (1,0,0,
    0,COS[beta],-SIN[beta],
    0,SIN[beta],COS[beta]);

    // multiply d and mat
    d = mat * d;

    //now we have a random vector around the x-axis
    //but we want it to be a random vector around "Normal", so we will rotate it by
    //ialphaxy and ialphaxz, to produce a vector around "Normal"


    //rotate the vector around the z-axis (by ialphaxy)
    mat.SetMatrix (COS[ialphaxy],-SIN[ialphaxy],0,
    SIN[ialphaxy],COS[ialphaxy],0,
    0,0,1);
    d = mat * d;

    //rotate the vector around the y-axis (by ialphaxz)
    mat.SetMatrix (COS[ialphaxz],0,SIN[ialphaxz],
    0,1,0,
    -SIN[ialphaxz],0,COS[ialphaxz]);
    d = mat * d;

    //thats all, we have a random vector, now we can do some extra stuff

    d.Normalize (); // unit-length

    //and strecht it to the desired length
    d *= iDesiredLength;

    return (d);
    }

    Have fun with it.
    Jan.
    GLIM - Immediate Mode Emulation for GL3

  2. #2
    Senior Member Regular Contributor
    Join Date
    Jul 2001
    Posts
    442

    Re: Random Vectors problem solved

    Lol! I was just working on tidying up my Vector class. I'll add this method in there too. I can imagine its going to be really useful.

    Thanks!

  3. #3
    Senior Member Frequent Contributor
    Join Date
    Aug 2000
    Location
    Cardiff University
    Posts
    653

    Re: Random Vectors problem solved

    Why not just add guassian noise to your vector?

  4. #4
    Senior Member OpenGL Guru
    Join Date
    Dec 2000
    Location
    Reutlingen, Germany
    Posts
    2,042

    Re: Random Vectors problem solved

    I donīt know, what gaussian noise is, but when you explain it to me, i might do it.

    Jan.
    GLIM - Immediate Mode Emulation for GL3

  5. #5
    Senior Member Regular Contributor
    Join Date
    Jul 2001
    Posts
    442

    Re: Random Vectors problem solved

    and when you've done it, I'll copy and paste it into my class

  6. #6
    Senior Member Regular Contributor
    Join Date
    Dec 2001
    Location
    Belmont, CA, USA
    Posts
    216

    Re: Random Vectors problem solved

    There is a problem -- a divide by zero if the vector is parallel to the Y axis.

    The easiest way to do it is to give your emitter an orientation (rather than just a direction), generate a random vector in the emitter's space according to your criteria, and then transform it into world space. My emitter creates random vectors in a cone around the Z axis:
    Code :
     
    vector r, v;
     
    a = randfloat( 0.f, CONE_ANGLE );
    b = randfloat( 0.f, TWO_PI );
     
    r.x = cos( b ) * sin( a );
    r.y = sin( b ) * sin( a );
    r.z = cos( a );
     
    v = EmitterSpaceToWorldSpace( r );

  7. #7
    Senior Member Regular Contributor
    Join Date
    Jul 2001
    Posts
    442

    Re: Random Vectors problem solved

    Originally posted by Jambolo:

    vector r, v;

    a = randfloat( 0.f, CONE_ANGLE );
    b = randfloat( 0.f, TWO_PI );

    r.x = cos( b ) * sin( a );
    r.y = sin( b ) * sin( a );
    r.z = cos( a );

    v = EmitterSpaceToWorldSpace( r );

    [/CODE]
    How to convert the emitter space to world space? Given Eye, Right and Up for the emitter, are you performing some kind of orthonormal basis transform? If so, how do you do this?

    Cheeeaaarrs.

  8. #8
    Senior Member OpenGL Guru
    Join Date
    Dec 2000
    Location
    Reutlingen, Germany
    Posts
    2,042

    Re: Random Vectors problem solved

    You are right, it should crash, if Normal is parallel to the y-axis because then Normal.x*Normal.x + Normal.z*Normal.z is zero. And it should also crash, when Normal is parallel to the z-axis, because then the same thing happens again.
    However i used the function with a vector that is parallel to the y-axis and it didnīt crash, thatīs strange.

    Well, you should just add two if-statements and test if lengthxy is zero or lengthxz is zero and if it is then you set ialphaxy or ialphaxz to zero. That should do it, i didnīt test it, yet.

    Chears,
    Jan.
    GLIM - Immediate Mode Emulation for GL3

  9. #9
    Senior Member OpenGL Pro
    Join Date
    Feb 2002
    Location
    Bonn, Germany
    Posts
    1,633

    Re: Random Vectors problem solved

    Wouldn't it be easier to just take the "approximate direction" vector, add some random number to each component, then normalize?

  10. #10
    Senior Member Regular Contributor
    Join Date
    Jul 2001
    Posts
    442

    Re: Random Vectors problem solved

    Wouldn't work. Well it would depend on the direction vector. Same with the spherical version above; most points will be around the poles of the sphere. What we need is a function that will provide a uniform distribution around the normal. No idea how to do this!

Page 1 of 2 12 LastLast

Similar Threads

  1. Random Input Problem [SOLVED]
    By g0bl1n in forum OpenGL: Basic Coding
    Replies: 1
    Last Post: 09-17-2011, 12:17 AM
  2. [Solved] GLM::lookAt and vectors.
    By Nvveen in forum OpenGL: General
    Replies: 0
    Last Post: 06-04-2011, 06:17 AM
  3. How to transform the random vectors around normal
    By Jedimaster in forum OpenGL: General
    Replies: 2
    Last Post: 04-06-2008, 03:13 PM
  4. This Problem Solved!!!!!
    By imported_TOMCAT in forum OpenGL: User Software
    Replies: 0
    Last Post: 01-05-2003, 07:21 AM
  5. Random Vectors
    By Jan in forum OpenGL: Advanced Coding
    Replies: 3
    Last Post: 06-07-2002, 07:08 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Proudly hosted by Digital Ocean