Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculate radius of helix so that models in helix are inside the frustum

I'm building an app in which I present some planes with textures. However, I would like to calculate the radius of the helix (which I use in my calculations to create a helix), dynamically based on the frustum width and the camera position.

The helix is positioned at the center of the screen x=0, y=0, z=0.

I would like this to take under consideration the screen orientation (landscape/ portrait).So far this is the code I have but it seems that I'm missing something because the planes at the left and the right are not inside the viewport.

App.prototype.calculateHelixRadius = function(){

    // plane width = height =  512;

    var friend = this.getFriend();
    var vFOV = friend.camera.fov * Math.PI / 180;
    var dist = utils.getAbsPointsDistance3D(friend.camera.position, friend.scene.position);
    var aspect = friend.settings.container.clientWidth / friend.settings.container.clientHeight;

    var frustumHeight = 2.0 * dist * Math.tan(0.5 * vFOV);
    var frustumWidth = frustumHeight * aspect;

    return utils.isLandscape() ? frustumHeight / 2 : frustumWidth / 2 ;

};

What am I doing wrong and why are the planes at the edges of the screen not inside?

Also for reference here is the code of getAbsPointsDistance3D

var utils = {

   // other helpers...

   getAbsPointsDistance3D: function(p1, p2) {

        var xd = p2.x - p1.x;
        var yd = p2.y - p1.y;
        var zd = p2.z - p1.z;

        return Math.sqrt(xd * xd + yd * yd + zd * zd);
    }

};

update

I tried decreasing the dist parameter but the results are not consistent...

like image 573
0x_Anakin Avatar asked Feb 19 '16 21:02

0x_Anakin


1 Answers

I wonder if the following explains your clipping.

You calculate your frustum characteristics, then calculate the helix radius using, say, the frustum width (width or height depending on the screen aspect...I may be getting some of the particulars wrong here because your question does not completely explain the details, but the general concepts still hold). The image below is a top view of the scenario which shows a circle representing the cylinder that encloses the helix. I believe you have calculated radius1. If so, note that there will be clipping of the cylinder (the shaded area), and thus the helix, in "front" of the cylinder centre.

enter image description here

Instead you need to calculate the cylinder/helix radius as shown in the second image, i.e. you need radius2. If the large angle at the image left is fov (again, vFOV? or hFOV?, etc., depending on whether your helix is going up-down or side-to-side, etc.), then its half angle is fov/2. This is the same angle shown in the centre of the cylinder. Thus, you need to decrease your helix radius as follows: radius2 = radius1 * cos(fov/2).

enter image description here

like image 179
Andrew Willems Avatar answered Sep 24 '22 15:09

Andrew Willems