POV-Ray : Newsgroups : povray.advanced-users : How to model a cube in 2D? Server Time
26 Nov 2024 04:32:51 EST (-0500)
  How to model a cube in 2D? (Message 1 to 6 of 6)  
From: Peter Popov
Subject: How to model a cube in 2D?
Date: 21 Jan 2001 03:06:15
Message: <em5l6tkaarfbmhmviq7p963t1g85qnaib2@4ax.com>
This will feel... a little strange.

Imagine a scene like this:

box { -1, 1 pigment { rgb 1 } rotate 60*y rotate -30*x}
camera { location -5*z look_at 0 orthographic }
light_source { <100,100,-100> color rgb 1 }

Now imagine I want to make it in a 2D program, for example Corel Draw
or Adobe illustrator. I want to start with a square for each face and
calculate

a) the necessary sequence of rotate and scale commands
b) the amount of light falling on it (flat shading) if the light
source position is known

Can anyone help me with the math involved? Remember, I only have
scale, rotate and tilt at my disposure, no matrices :(

BTW the amounts of rotation along the y and x axes are arbitrary.


Peter Popov ICQ : 15002700
Personal e-mail : pet### [at] vipbg
TAG      e-mail : pet### [at] tagpovrayorg


Post a reply to this message

From: Josh English
Subject: Re: How to model a cube in 2D?
Date: 22 Jan 2001 08:29:39
Message: <3A6C35C1.39A3F238@spiritone.com>
Since you are using an orthographic camera, you need to decide what the
image bounds are. The standard up y and right 4/3*x will mean that this
box will be outside the image plane. That's a problem for later, however.
The big trick is setting up a formula that takes the 3d points and
rotates them. YOu might not have a matrix command available, but that's
exactly what you need to look at for this. You can't use the matrix, but
you can use each row of the matrix in new declarations.

You will have eight coordinates for the eight vertices of the box, and I
would leave them in 3D until the very end. So image we have an array
containing those points, for each element of the array you have the
standard x, y, and z coordinates:

(From Johns Matrix page) To rotate a position p by y*theta
newp.x = cos(theta)*p.x - sin(theta)*p.z
newp.y = p.y
newp.z = sin(theta)*p.x + cos(theta)*p.z
p = newp

Then do the conversions for the other rotations.

Once you've done that you need to worry abount converting it to the
coords of the 2d image plane on a point we'll label drawp. The simplest
rule is to ignore the z coordinate:
drawp(p).x = p.x
drawp(p).y = p.y
I beleive that an orthographic camera may use that, but It's 5:30 as I
write this and I've only had two cups of coffee.

Another method might be to add the z coordinate
drawp(p).x = p.x + p.z   or  p.x + (1/3)*p.z
drawp(p).y = p.y + p.z   or p.y + (2/3)*p.z

As for lighting, I'd have to think about that a bit more. If each face
was going to get a flat shade of color, I'd probably take the average of
its four corners, and play with angles from light to the point and from
the camera to the point to judge what kind of shading to put there.

Josh
Peter Popov wrote:

> This will feel... a little strange.
>
> Imagine a scene like this:
>
> box { -1, 1 pigment { rgb 1 } rotate 60*y rotate -30*x}
> camera { location -5*z look_at 0 orthographic }
> light_source { <100,100,-100> color rgb 1 }
>
> Now imagine I want to make it in a 2D program, for example Corel Draw
> or Adobe illustrator. I want to start with a square for each face and
> calculate
>
> a) the necessary sequence of rotate and scale commands
> b) the amount of light falling on it (flat shading) if the light
> source position is known
>
> Can anyone help me with the math involved? Remember, I only have
> scale, rotate and tilt at my disposure, no matrices :(
>
> BTW the amounts of rotation along the y and x axes are arbitrary.
>
> Peter Popov ICQ : 15002700
> Personal e-mail : pet### [at] vipbg
> TAG      e-mail : pet### [at] tagpovrayorg

--
Josh English -- Lexiphanic Lethomaniac
eng### [at] spiritonecom
The POV-Ray Cyclopedia http://www.spiritone.com/~english/cyclopedia/


Post a reply to this message

From: Peter Popov
Subject: Re: How to model a cube in 2D?
Date: 23 Jan 2001 14:05:36
Message: <qnir6tkibl7mngr1068p601c04gphvtkv1@4ax.com>
On Mon, 22 Jan 2001 05:29:37 -0800, Josh English
<eng### [at] spiritonecom> wrote:

>You will have eight coordinates for the eight vertices of the box, and I
>would leave them in 3D until the very end. So image we have an array
>containing those points, for each element of the array you have the
>standard x, y, and z coordinates:

>(From Johns Matrix page) To rotate a position p by y*theta
>newp.x = cos(theta)*p.x - sin(theta)*p.z
>newp.y = p.y
>newp.z = sin(theta)*p.x + cos(theta)*p.z
>p = newp
>
>Then do the conversions for the other rotations.

That's exactly what I am doing, though in a RHS coor. system the signs
are a bit different.

>As for lighting, I'd have to think about that a bit more. If each face
>was going to get a flat shade of color, I'd probably take the average of
>its four corners, and play with angles from light to the point and from
>the camera to the point to judge what kind of shading to put there.

I'd just take the plane formed by 3 of the points and calculate the
angle between the normal and the camera ray. Lighting is not my main
problem.

I have some trouble with the 3D calculations but I'll see if John's
page will help me solve them.

However, I still don't have a clue how to proceed once I have the
screen coordinates of the vertices. I have to start with a square and
scale, rotate & tilt it to its deformed shape. It is possible since a
cube face in orthographic projection will always be a parallelogram,
but how?


Peter Popov ICQ : 15002700
Personal e-mail : pet### [at] vipbg
TAG      e-mail : pet### [at] tagpovrayorg


Post a reply to this message

From: Joshua English
Subject: Re: How to model a cube in 2D?
Date: 24 Jan 2001 12:05:12
Message: <3A6F0B45.67DE794C@spiritone.com>
Peter Popov wrote:

> On Mon, 22 Jan 2001 05:29:37 -0800, Josh English
> <eng### [at] spiritonecom> wrote:
>
> >You will have eight coordinates for the eight vertices of the box, and I
> >would leave them in 3D until the very end. So image we have an array
> >containing those points, for each element of the array you have the
> >standard x, y, and z coordinates:
>
> >(From Johns Matrix page) To rotate a position p by y*theta
> >newp.x = cos(theta)*p.x - sin(theta)*p.z
> >newp.y = p.y
> >newp.z = sin(theta)*p.x + cos(theta)*p.z
> >p = newp
> >
> >Then do the conversions for the other rotations.
>
> That's exactly what I am doing, though in a RHS coor. system the signs
> are a bit different.

I'm not familiar with that coordinatge system. Is that a cylindrical or
spherical system?

>
>
> >As for lighting, I'd have to think about that a bit more. If each face
> >was going to get a flat shade of color, I'd probably take the average of
> >its four corners, and play with angles from light to the point and from
> >the camera to the point to judge what kind of shading to put there.
>
> I'd just take the plane formed by 3 of the points and calculate the
> angle between the normal and the camera ray. Lighting is not my main
> problem.
>
> I have some trouble with the 3D calculations but I'll see if John's
> page will help me solve them.
>
> However, I still don't have a clue how to proceed once I have the
> screen coordinates of the vertices. I have to start with a square and
> scale, rotate & tilt it to its deformed shape. It is possible since a
> cube face in orthographic projection will always be a parallelogram,
> but how?

Once you determine where the point is in 3D space, it has to be fitted to
the drawing plane. The method I was think of does everything in 3D as far as
placement, and then compresses it to the plane. Once it's in a 2D form, it
wouldn't need to be rotated again. That's what the draw.x and draw.y lines
were trying to do (Not that they were particularly accurate, but that's the
theory I was working with). The other issue I was thinking about was that in
3D, the origin is usually set at the center, but in 2D, the origin is usual
the upper left or lower left corner.

I know it seems to be the long way around, but I can't think of any way to
use 2D coords only  and mimic 3D shape.

Josh


Post a reply to this message

From: Rune
Subject: Re: How to model a cube in 2D?
Date: 24 Jan 2001 12:49:03
Message: <3a6f158f@news.povray.org>
"Peter Popov" wrote:
> I still don't have a clue how to proceed once I have the
> screen coordinates of the vertices. I have to start with
> a square and scale, rotate & tilt it to its deformed shape.
> It is possible since a cube face in orthographic projection
> will always be a parallelogram, but how?

Well, you could start with finding the width and height of the
input-face-parallelogram, and scale the output-face so it has the same
proportions. The you can find the angle of one of the corners in the
input-face and tilt the output-face so it has the same angle in the corner.
Then find out how much you must rotate the output-face to match the
input-face. Finally translate it if that's necessary.

Hope that helps. If you need more details, I'll need more details first...
:)

Rune
--
\ Include files, tutorials, 3D images, raytracing jokes,
/ The POV Desktop Theme, and The POV-Ray Logo Contest can
\ all be found at http://rsj.mobilixnet.dk (updated January 6)
/ Also visit http://www.povrayusers.org


Post a reply to this message

From: Tor Olav Kristensen
Subject: Re: How to model a cube in 2D?
Date: 24 Jan 2001 21:22:26
Message: <3A6F8DA3.952D3A41@online.no>
Peter Popov wrote:
>...
> I have some trouble with the 3D calculations but I'll see if John's
> page will help me solve them.
>...
 
I don't know what your 3D-troubles are, but maybe 
the code below solves some of them.

Please ask if you want me to comment on the code.

Note that the code is made for POV's Left Handed System.

--
Best regards,

Tor Olav


// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7 =
// Copyright 2001 by Tor Olav Kristensen
// mailto:tor### [at] hotmailcom
// http://www.crosswinds.net/~tok/tokrays.html
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7 =

#version 3.1;

#include "colors.inc"

global_settings { ambient_light color White }

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

#macro vproject(v1, v2)
// Projection of the vector v1 in the direction of the vector v2.

  (v2*vdot(v1, v2)/vdot(v2, v2))

#end // macro vproject


#macro pt2pl(pPoint, pPlane, vPlane)
// Projection of a point to a plane

  (pPoint - vproject(pPoint - pPlane, vPlane))

#end // macro pt2pl


/*
#macro ln2pl(pLine, vLine, pPlane, vPlane)
// Intersection of a line and a plane

  (pLine + vLine*vdot(pPlane - pLine, vPlane)/vdot(vLine, vPlane))

#end // macro ln2pl
*/


#macro v2D3D(v2D, vBas1, vBas2)

  (v2D.u*vBas1 + v2D.v*vBas2)

#end // macro v2D3D


#macro v3D2D(v3D, vBas1, vBas2)

  <vdot(v3D, vBas1), vdot(v3D, vBas2)>

#end // macro v3D2D


#macro SphereSpread(CenterArray, Radius)

  #local Cnt = 0;
  #while (Cnt < dimension_size(CenterArray, 1))
    sphere { CenterArray[Cnt], Radius }
    #local Cnt = Cnt + 1;
  #end // while

#end // macro SphereSpread 


#macro CylinderSpread(EndsArray, ConnectArray, Radius)

  #local Cnt = 0;
  #while (Cnt < dimension_size(ConnectArray, 1))
    cylinder {
      EndsArray[ConnectArray[Cnt][0]],
      EndsArray[ConnectArray[Cnt][1]],
      Radius
    }
    #local Cnt = Cnt + 1;
  #end // while

#end // macro CylinderSpread


#macro CylindersBetween(EndsArray1, EndsArray2, Radius)

  #local Cnt = 0;
  #while (Cnt < dimension_size(EndsArray1, 1))
    cylinder {
      EndsArray1[Cnt],
      EndsArray2[Cnt],
      Radius
    }
    #local Cnt = Cnt + 1;
  #end // while

#end // macro CylindersBetween

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

#declare NrOfCorners = 8;

#declare ArrayOfCorners =
array[NrOfCorners] {
  < 1, -1,  1>, <-1, -1,  1>, <-1, -1, -1>, < 1, -1, -1>, 
  < 1,  1,  1>, <-1,  1,  1>, <-1,  1, -1>, < 1,  1, -1>
}  


#declare NrOfEdges = 12;

#declare ArrayOfEdges =
array[NrOfEdges][2] {
  { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 0 },
  { 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 4 },
  { 0, 4 }, { 1, 5 }, { 2, 6 }, { 3, 7 }
}  

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

#declare pAnyOffSet = <2, 1, -1>;
#declare vAnyRot = <30, 15, -20>;
#declare vAnyScale = <0.6, 1, 1.8>;

#declare Cnt = 0;
#while (Cnt < NrOfCorners)
  #declare ArrayOfCorners[Cnt] = ArrayOfCorners[Cnt] + pAnyOffSet;
  #declare ArrayOfCorners[Cnt] =  vrotate(ArrayOfCorners[Cnt], vAnyRot);
//  #declare ArrayOfCorners[Cnt] = ArrayOfCorners[Cnt]*vAnyScale;
  #declare Cnt = Cnt + 1;
#end // while

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

union {
  SphereSpread(ArrayOfCorners, 0.15)
  pigment { color Yellow }
}

union {
  CylinderSpread(ArrayOfCorners, ArrayOfEdges, 0.1)
  pigment { color Red }
}

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

#declare pPlane = -2*<1, 1, 1>;
#declare vPlane = <3, 1, 2>;

disc {
  pPlane, vPlane, 5
  pigment { color White }
}

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

#declare ArrayOfProjectedCorners = array[NrOfCorners]

#declare Cnt = 0;

#while (Cnt < NrOfCorners)
  #declare ArrayOfProjectedCorners[Cnt] =
    pt2pl(ArrayOfCorners[Cnt], pPlane, vPlane);
  #declare Cnt = Cnt + 1;
#end // while


/*
union {
  SphereSpread(ArrayOfProjectedCorners, 0.16)
  pigment { color White }
}

union {
  CylinderSpread(ArrayOfProjectedCorners, ArrayOfEdges, 0.11)
  pigment { color Gray }
}
*/

union {
  CylindersBetween(ArrayOfCorners, ArrayOfProjectedCorners, 0.05)
  pigment { color Orange }
}

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

#declare pOrigo2D = pt2pl(<0, 0, 0>, pPlane, vPlane);

sphere {
  pOrigo2D, 0.15
  pigment { color Magenta }
}

#declare vBasisU = vnormalize(vcross(vPlane, y));
#declare vBasisV = vnormalize(vcross(vBasisU, vPlane));

cylinder {
  pOrigo2D, pOrigo2D + 3*vBasisU, 0.1
  pigment { color Green }
}

cylinder {
  pOrigo2D, pOrigo2D + 3*vBasisV, 0.1
  pigment { color Green }
}

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

#declare ArrayOfCorners2D = array[NrOfCorners]

#declare Cnt = 0;
#while (Cnt < NrOfCorners)
  #declare ArrayOfCorners2D[Cnt] =
    v3D2D(ArrayOfProjectedCorners[Cnt] - pOrigo2D, vBasisU, vBasisV);
  #declare Cnt = Cnt + 1;
#end // while


#declare ArrayOfReconstructedCorners = array[NrOfCorners]

#declare Cnt = 0;
#while (Cnt < NrOfCorners)
  #declare ArrayOfReconstructedCorners[Cnt] =
    pOrigo2D + v2D3D(ArrayOfCorners2D[Cnt], vBasisU, vBasisV);
  #declare Cnt = Cnt + 1;
#end // while


union {
  SphereSpread(ArrayOfReconstructedCorners, 0.15)
  pigment { color Blue }
}

union {
  CylinderSpread(ArrayOfReconstructedCorners, ArrayOfEdges, 0.1)
  pigment { color Cyan }
}

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

#declare vBasisU = x;
#declare vBasisV = y;

#declare ArrayOfNewCorners = array[NrOfCorners]

#declare Cnt = 0;
#while (Cnt < NrOfCorners)
  #declare ArrayOfNewCorners[Cnt] =
    v2D3D(ArrayOfCorners2D[Cnt], vBasisU, vBasisV);
  #declare Cnt = Cnt + 1;
#end // while

// Uncomment the other camera to see this
union {
  union {
    SphereSpread(ArrayOfNewCorners, 0.15)
    pigment { color White }
  }
  union {
    CylinderSpread(ArrayOfNewCorners, ArrayOfEdges, 0.1)
    pigment { color Yellow }
  }
  sphere {
    <0, 0, 0>, 0.15
    pigment { color Magenta }
  }
  cylinder {
    <0, 0, 0>, 3*vBasisU, 0.1
    pigment { color Green }
  }
  cylinder {
    <0, 0, 0>, 3*vBasisV, 0.1
    pigment { color Green }
  }
  translate 20*y
}

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

background { color Blue/2 }

light_source {
  100*<4, 2, -1>
  color White*1.5
  shadowless
}

camera {
  location <2, 1, -3>*2.5
  look_at pOrigo2D/2
}

/*
camera {
  location -8*vnormalize(vcross(vBasisU, vBasisV))
  look_at <0, 0, 0>
  translate 20*y
}

plane {
  -z, 0
  pigment { color Gray }
}
*/

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


Post a reply to this message

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