Deciphering one cryptic line of code : trigonometry and plane definition

175 Views Asked by At

Thank you

-3 votes for a question that was correctly written, on-topic (since when programming and geometry don't belong on StackOverflow ?), and could have helped bring an interesting piece of software to publicity one day, thanks to people helpfulness.

It was not perfectly clear but could have been enhanced if people didn't downvote it straight away, which is now a deterrent to any kind of future for this question.

People have the nasty tendency here to prefering downvote instead of lending a hand. So much for tolerance and open-mindedness.

I'll just leave this picture as a proof the program I was trying to un-obscure is a worthy piece of software that could have interested many. If it ever gets public one day it will certainly not be thanks to a bunch of stupid downvoters.

enter image description here

The original question

I'm trying to decipher an obscure part of a program that I want to port to better readability form.

The only documentation accompanies this piece of code tells me we are generating a random plane in space from two "direction cosines" and a distance from the origin. I've tried all day to decipher the program, and I've made progress, but I'm stuck one one specific line which still eludes me.

The specific line seems to be about : generating the a,b,c components of the normal vector (which are also the a, b, c in the equation of the plane) from two angles, one which I understand to be the angle between the Z axis and the normal, and the other angle between the X axis and the normal.

All the variables had obscure names, I've renamed a few, when I understood their meaning, to more explicit names. The person who wrote this code is no longer here to give any explanation.

The only output that is subsequently used is the three normal components normal_a, normal_b, and normal_c.

In this first part the code generates the random parameters for the plane.

void Plane::generate(int i) // the index of this plane
                              // as a sequence of planes is being generated here
{
    t_pt = (i + 10)*rnd_float() / 2; // this looks a lot like the distance
                                     //                         from the origin

    t_ap = rnd_float() * PI * 2; // rnd_float() returns a rand float between 0 and 1

    t_at = rnd_float() * PI * 2;
    t_it = (.5 - rnd_float())*PI*.025*COEFF_TRANS; // COEFF_TRANS = 1.5

    t_aa = rnd_float() * PI * 2;
    t_ia = (.5 - rnd_float())*PI*.0025*.5*COEFF_TRANS;

Then it determines the coordinates of the normal of the vector

    t_at = t_at + t_it; // this is most probably the angle from Z axis to normal
    float ptt = t_pt + cos(t_at)*.01*t_pt * t_pt; // <<<<<< the obscure line

    normal_c = 1 / (sqrt(1 + ptt*ptt)); // length of normal Z component = c
    normal_ab = sqrt(1 - normal_c*normal_c); // length of normal XY component = ab

    t_aa = t_aa + t_ia * .31; // this is the other angle, from X or Y axis to normal
    float pa = t_ap + cos(t_aa)*.05; // a bit obscure here also

    normal_a = normal_ab*cos(pa);
    normal_b = normal_ab*sin(pa);
}

The specific line that eludes me is the first line here :

    float ptt = t_pt + cos(t_at)*.01*t_pt * t_pt;

    normal_c = 1 / (sqrt(1 + ptt*ptt)); // length of normal Z component = c

I really have a hard time understanding what this ptt variable can represent. If I would have to calculate the normal_c myself I guess it would only involve a cosine and an angle.

If we translate the code to what I understand it is doing, it would look like this, but it doesn't help me guess what ptt represents :

    float ptt = planeDistance + cos(angleZToNormal)*.01*planeDistance*planeDistance;

I've supposed that the next line, calculating the z length of normal_c as this is done here probably relies on the formula : cos(angle) = A / (sqrt(A² + O²)) with A being the length of adjacent and O being the lenght of opposite side. But that's only a guess.

Any pointers or clues from people more experienced with trigonometry that could set me on the right track would be greatly appreciated. Thanks !

1

There are 1 best solutions below

3
On

I still couldn't really tell you what this is doing, but I wanted to share my progress at least:

float rnd_float() {return rand() / (RAND_MAX + 1.0f);}

void generate(int i) // the index of this plane
                     // as a sequence of planes is being generated here
{
    // generate a random angle B and offset it a bit, randomly
    float angle_B = rnd_float() * 2.0f * PI,        // angle from 0 to 2 pi
        offset_B = (0.5f - rnd_float()) * PI        // angle from -pi to pi,
            * (.025f * COEFF_TRANS);                // times some scaling factor

    angle_B += offset_B;                            // offset the angle B


    // generate a random angle C and offset it a bit, randomly
    float angle_C = rnd_float() * 2.0f * PI,        // angle from 0 to 2 pi
        offset_C = (0.5f - rnd_float()) * PI        // angle from -pi to pi,
            * (.0025f * .5f * COEFF_TRANS) * .31f;  // times two scaling factors

    angle_C += offset_C;                            // offset the angle D


    // some sort of distance?
    float dist = (i + 10) * rnd_float() / 2;
    // generate a random angle A from 0 to 2 pi
    float angle_A = rnd_float() * 2.0f * PI;

    // no idea
    float ptt =    dist + cos(angle_B) * dist * dist * 0.01f;
    // ditto
    float pa  = angle_A + cos(angle_C) * .05f;


    // still not sure what they're doing here, but rearraged it a bit
    float normal_c  =        1 / sqrt(1 + ptt * ptt), // length of normal Z?
          normal_ab = abs(ptt) / sqrt(1 + ptt * ptt); // length of normal XY?

    float normal_a = normal_ab * cos(pa);
          normal_b = normal_ab * sin(pa);
}

note that

t_pt -> dist
t_ap -> angle_A
t_at -> angle_B
t_aa -> angle_C

Other things of note, the generated a, b, and c values do constitute a properly normalized unit vector and running your code multiple times for different i gives the following:

Avg magnitudes Phi distribution