POV-Ray : Newsgroups : povray.general : perspective user defined camera? : Re: perspective user defined camera? Server Time
26 Apr 2024 17:23:28 EDT (-0400)
  Re: perspective user defined camera?  
From: Tor Olav Kristensen
Date: 27 Jan 2019 18:50:01
Message: <web.5c4e437c62f29219264be49d0@news.povray.org>
ingo <ing### [at] tagpovrayorg> wrote:
> in news:web.5c4d6e4362f292196ac8a0470@news.povray.org Tor Olav
> Kristensen wrote:
>
> > Alternatively you can keep pLookAt and vDirection and then compose a
> > "look at" transformation and apply it to the vRight and vUp vectors.
> >
> >
>
> Thank you Tor Olav!! Matrices are scary ;) I'll give it a go,

No problem. It was an interesting problem to solve.

You don't have to deal much with matrices to do this. (I just showed the
relationship in case anyone is interested.)

Below is some more code for you.

--
Tor Olav
http://subcube.com

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

#version 3.8;

global_settings { assumed_gamma 1.0 }

#include "colors.inc"
#include "transforms.inc"

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// Default directions for both camera types. (The default right vector
// can be considered to be +1*x for the user defined camera.)

#declare vDirection_0 = +1*z;
#declare vRight_0 = +image_width/image_height*x;
#declare vUp_0 = +1*y;

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

#declare SphereRadius = 0.1;

#declare pLocation = <0.0, 0.5, -6.0>;
#declare Angle = 90;

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

#declare PerspectiveCamera_0 =
    camera {
        perspective
        location pLocation
        direction vDirection_0
        right vRight_0
        up vUp_0
        angle Angle
    }

#declare LocationX = pLocation.x;
#declare LocationY = pLocation.y;
#declare LocationZ = pLocation.z;

#declare D0_X_Fn = function(u, v) { image_width*u };
#declare D0_Y_Fn = function(u, v) { image_height*v };
#declare D0_Z_Fn = function(u, v) { image_width/2/tan(radians(Angle/2)) };

#declare UserDefinedCamera_0 =
    camera {
        user_defined
        location {
            function { LocationX }
            function { LocationY }
            function { LocationZ }
        }
        direction {
            function { D0_X_Fn(u, v) }
            function { D0_Y_Fn(u, v) }
            function { D0_Z_Fn(u, v) }
        }
    }

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

#declare pLookAt = <+1.5, -1.0, 1.0>;

// This sphere should stay in center for these cameras
// sphere { pLookAt, SphereRadius pigment { Magenta } }

#declare vLookAt = pLookAt - pLocation;
#declare LookAtTransform = Reorient_Trans(z, vLookAt)

#declare vDirection_1 = vtransform(vDirection_0, LookAtTransform);
#declare vRight_1 = vtransform(vRight_0, LookAtTransform);
#declare vUp_1 = vtransform(vUp_0, LookAtTransform);

#declare PerspectiveCamera_1 =
    camera {
        perspective
        location pLocation
        direction vDirection_1
        right vRight_1
        up vUp_1
        angle Angle
    }

#declare vT1_X = vtransform(x, LookAtTransform);
#declare X1_X = vT1_X.x;
#declare X1_Y = vT1_X.y;
#declare X1_Z = vT1_X.z;

#declare vT1_Y = vtransform(y, LookAtTransform);
#declare Y1_X = vT1_Y.x;
#declare Y1_Y = vT1_Y.y;
#declare Y1_Z = vT1_Y.z;

#declare vT1_Z = vtransform(z, LookAtTransform);
#declare Z1_X = vT1_Z.x;
#declare Z1_Y = vT1_Z.y;
#declare Z1_Z = vT1_Z.z;

#declare D1_X_Fn =
    function(u, v) {
        0
        + X1_X*D0_X_Fn(u, v)
        + Y1_X*D0_Y_Fn(u, v)
        + Z1_X*D0_Z_Fn(u, v)
    }
;
#declare D1_Y_Fn =
    function(u, v) {
        0
        + X1_Y*D0_X_Fn(u, v)
        + Y1_Y*D0_Y_Fn(u, v)
        + Z1_Y*D0_Z_Fn(u, v)
    }
;
#declare D1_Z_Fn =
    function(u, v) {
        0
        + X1_Z*D0_X_Fn(u, v)
        + Y1_Z*D0_Y_Fn(u, v)
        + Z1_Z*D0_Z_Fn(u, v)
    }
;
#declare UserDefinedCamera_1 =
    camera {
        user_defined
        location {
            function { LocationX }
            function { LocationY }
            function { LocationZ }
        }
        direction {
            function { D1_X_Fn(u, v) }
            function { D1_Y_Fn(u, v) }
            function { D1_Z_Fn(u, v) }
        }
    }

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

#declare vNewDirection = <1.5, 1.0, 10>;
#declare RotationAngle = 55;

// This sphere should stay in center for these cameras while rotating
// them around the vNewDirection vector
// sphere { pLocation + vNewDirection, SphereRadius pigment { Cyan } }

#declare AnotherTransform =
    transform {
        Reorient_Trans(vDirection_1, vNewDirection)
        Axis_Rotate_Trans(vNewDirection, RotationAngle)
    }

#declare PerspectiveCamera_2a =
    camera {
        PerspectiveCamera_1
        transform {
            translate -pLocation
            AnotherTransform
            translate +pLocation
        }
    }

#declare vDirection_2 = vtransform(vDirection_1, AnotherTransform);
#declare vRight_2 = vtransform(vRight_1, AnotherTransform);
#declare vUp_2 = vtransform(vUp_1, AnotherTransform);

#declare PerspectiveCamera_2b =
    camera {
        perspective
        location pLocation
        direction vDirection_2
        right vRight_2
        up vUp_2
        angle Angle
    }

#declare vT2_X = vtransform(x, AnotherTransform);
#declare X2_X = vT2_X.x;
#declare X2_Y = vT2_X.y;
#declare X2_Z = vT2_X.z;

#declare vT2_Y = vtransform(y, AnotherTransform);
#declare Y2_X = vT2_Y.x;
#declare Y2_Y = vT2_Y.y;
#declare Y2_Z = vT2_Y.z;

#declare vT2_Z = vtransform(z, AnotherTransform);
#declare Z2_X = vT2_Z.x;
#declare Z2_Y = vT2_Z.y;
#declare Z2_Z = vT2_Z.z;

#declare D2_X_Fn =
    function(u, v) {
        0
        + X2_X*D1_X_Fn(u, v)
        + Y2_X*D1_Y_Fn(u, v)
        + Z2_X*D1_Z_Fn(u, v)
    }
;
#declare D2_Y_Fn =
    function(u, v) {
        0
        + X2_Y*D1_X_Fn(u, v)
        + Y2_Y*D1_Y_Fn(u, v)
        + Z2_Y*D1_Z_Fn(u, v)
    }
;
#declare D2_Z_Fn =
    function(u, v) {
        0
        + X2_Z*D1_X_Fn(u, v)
        + Y2_Z*D1_Y_Fn(u, v)
        + Z2_Z*D1_Z_Fn(u, v)
    }
;
#declare UserDefinedCamera_2 =
    camera {
        user_defined
        location {
            function { LocationX }
            function { LocationY }
            function { LocationZ }
        }
        direction {
            function { D2_X_Fn(u, v) }
            function { D2_Y_Fn(u, v) }
            function { D2_Z_Fn(u, v) }
        }
    }

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

/*
camera { PerspectiveCamera_0 }
camera { UserDefinedCamera_0 }

camera { PerspectiveCamera_1 }
camera { UserDefinedCamera_1 }

camera { PerspectiveCamera_2a }
camera { PerspectiveCamera_2b }
camera { UserDefinedCamera_2 }
*/

camera { UserDefinedCamera_2 }

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

sphere { < 0,  0,  2>, SphereRadius pigment { checker White Black } }
sphere { < 0,  0, -2>, SphereRadius pigment { checker White Red   } }
sphere { < 2,  0,  0>, SphereRadius pigment { checker White Green } }
sphere { <-2,  0,  0>, SphereRadius pigment { checker White Blue  } }

union {
    sphere { < 0,  0,  2>, SphereRadius pigment { White } }
    sphere { < 0,  0, -2>, SphereRadius pigment { Red   } }
    sphere { < 2,  0,  0>, SphereRadius pigment { Green } }
    sphere { <-2,  0,  0>, SphereRadius pigment { Blue  } }
    translate 0.5*y
}

background { color Gray20 }

light_source { <1, 1, -1>*100 White }
light_source { <0, 0, 0> Gray10 }

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.