3d2dproblems

3d2dproblems

Post by Arka » Thu, 10 Jul 2003 13:26:19



Hi All!

Help me please

the problem with 3d and 2d graphics

i have Rectangle and i need rotate it
i'll do it from the rotation matrix

TForm1::P3d __fastcall TForm1::R(TForm1::P3d thk,double angel)
{
  P3d t;
  t.x=thk.x*cos(angel)-thk.x*sin(angel)+thk.x;
  t.y=thk.y;
  t.z=thk.z*sin(angel)+thk.z*cos(angel)+thk.z;
  return t;

Quote:}

and then translate it to the 2d by

TForm1::P3d __fastcall TForm1::DD(TForm1::P3d thk,TForm1::P3d c)
{
  P3d t;
  t.x=c.x+thk.x+thk.z/1.4;
  t.y=c.y+thk.y-thk.z/1.4;
  t.z=thk.z;
  return t;
  //c.x and c.y is the center

Quote:}

where P3d is
struct P3d
{
  double x,y,z;

Quote:};

and where angel is angle

i v rotate it by the timer
when it begin's at first it stand begear then smaler but a little it rotate
and then it fly away
i don't know what to do please help me!
if need i can give full code

with best regards Arkan.

 
 
 

3d2dproblems

Post by Dave Eberl » Thu, 10 Jul 2003 14:03:14



>   t.x=thk.x*cos(angel)-thk.x*sin(angel)+thk.x;
>   t.y=thk.y;
>   t.z=thk.z*sin(angel)+thk.z*cos(angel)+thk.z;

Try
  t.x = thk.x*cos(angel) - thk.y*sin(angel) + thk.z;
  t.y = thk.y;
  t.z = thk.x*sin(angel) + thk.y*cos(angel) + thk.z;

--
Dave Eberly

http://www.magic-software.com
http://www.wild-magic.com

 
 
 

3d2dproblems

Post by Arka » Thu, 10 Jul 2003 14:27:49


i can't understand why rectangel is flying away
and can't understand why the variable angel is changed so strange
may be somebody else know

here's code of cpp

//--------------------------------------------------------------------------
-

#include <vcl.h>
#include <math.h>

#pragma hdrstop

#include "Unit1.h"
//--------------------------------------------------------------------------
-
#pragma package(smart_init)
#pragma resource "*.dfm"

TForm1 *Form1;

//--------------------------------------------------------------------------
-
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{

Quote:}

TForm1::P3d __fastcall TForm1::calculate(P3d pixel,double angel)
{
  P3d t;
  P3d base = { 335, 275, 0 };
  pixel.x -= base.x;
  pixel.y -= base.y;
  t.x=pixel.x*cos(angel)-pixel.y*sin(angel)+base.x;
  t.y=pixel.x*sin(angel)+pixel.y*cos(angel)+base.y;

  t.z=pixel.z;
  return t;

Quote:}

//--------------------------------------------------------------------------
-

TForm1::P3d __fastcall TForm1::R(TForm1::P3d thk,double angel)
{
  P3d t;
  t.x = thk.x*cos(angel) - thk.y*sin(angel) + thk.z;
  t.y = thk.y;
  t.z = thk.x*sin(angel) + thk.y*cos(angel) + thk.z;

  /*t.x=thk.x*cos(angel)-thk.x*sin(angel)+thk.x;
  t.y=thk.y;
  t.z=thk.z*sin(angel)+thk.z*cos(angel)+thk.z;*/
  return t;

Quote:}

TForm1::P3d __fastcall TForm1::DD(TForm1::P3d thk,TForm1::P3d c)
{
  P3d t;
  t.x=c.x+thk.x+thk.z/1.4;
  t.y=c.y+thk.y-thk.z/1.4;
  t.z=thk.z;
  return t;
Quote:}

void __fastcall TForm1::FormCreate(TObject *Sender)
{
line[0].x=0;
line[0].y=0;
line[0].z=0;
line[1].x=50;
line[1].y=0;
line[1].z=0;
line[2].x=0;
line[2].y=0;
line[2].z=20;
line[3].x=50;
line[3].y=0;
line[3].z=20;
angel=0;
Quote:}

//--------------------------------------------------------------------------
-
void __fastcall TForm1::Connect(TForm1::P3d line[3])
{
int i;
for (i=0;i<=3;i++)
{PaintBox1->Canvas->TextOutA(line[i].x,line[i].y,i);}
PaintBox1->Canvas->MoveTo(line[0].x,line[0].y);
PaintBox1->Canvas->LineTo(line[1].x,line[1].y);
PaintBox1->Canvas->LineTo(line[3].x,line[3].y);
PaintBox1->Canvas->LineTo(line[2].x,line[2].y);
PaintBox1->Canvas->LineTo(line[0].x,line[0].y);

Quote:}

void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
int i;
TForm1::P3d center={150,100,1};
for (i=0;i<=4;i++)
{
  line[i]=R(line[i],angel);
  line[i]=DD(line[i],center);

Quote:}

angel=(angel==360?angel=0:angel+=1);

Connect(line);
//for (int i=0;i<=3;i++)
/*{
Connect(line);
if (angel==360) {angel=0;} else angel+=0.1;
line[0]=calculate(line[0],angel);
line[1]=calculate(line[1],angel);
line[2]=calculate(line[2],angel);
line[3]=calculate(line[3],angel);
int i;*/
ListBox1->Clear();
for (i=0;i<4;i++)
{
ListBox1->Items->Add(i);
ListBox1->Items->Add("===================");
ListBox1->Items->Add(line[i].x);
ListBox1->Items->Add(line[i].y);
ListBox1->Items->Add(angel);
ListBox1->Items->Add("cos(l) = "+String(cos(angel)));
ListBox1->Items->Add("sin(l) = "+String(sin(angel)));
ListBox1->Items->Add("===================");

Quote:}

/*PaintBox1->Canvas->MoveTo(line[0].x,line[0].y);

PaintBox1->Canvas->LineTo(line[1].x,line[1].y);

Quote:}*/
}

//--------------------------------------------------------------------------
-

//--------------------------------------------------------------------------
-

//--------------------------------------------------------------------------
-

//--------------------------------------------------------------------------
-

void __fastcall TForm1::Button1Click(TObject *Sender)
{
Timer1Timer(Sender);

Quote:}

//--------------------------------------------------------------------------
-

void __fastcall TForm1::Timer2Timer(TObject *Sender)
{
Edit1->Text=String(angel);

Quote:}

//--------------------------------------------------------------------------
-

here is h

//--------------------------------------------------------------------------
-

#ifndef Unit1H
#define Unit1H
//--------------------------------------------------------------------------
-
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
//--------------------------------------------------------------------------
-
class TForm1 : public TForm
{
__published: // IDE-managed Components
        TPaintBox *PaintBox1;
        TButton *Button1;
        TTimer *Timer1;
        TListBox *ListBox1;
        TEdit *Edit1;
        TTimer *Timer2;
        void __fastcall FormCreate(TObject *Sender);
        void __fastcall Timer1Timer(TObject *Sender);
        void __fastcall Button1Click(TObject *Sender);
        void __fastcall Timer2Timer(TObject *Sender);
private: // User declarations
public:  // User declarations
struct P3d
{
 double x,y,z;

Quote:};

P3d line[4];
double angel;
        __fastcall TForm1(TComponent* Owner);
        P3d __fastcall calculate(P3d pixel,double angel);
        void __fastcall Connect(TForm1::P3d line[3]);
        P3d __fastcall DD(P3d thk,P3d c);
        TForm1::P3d __fastcall R(TForm1::P3d thk,double angel);
Quote:};

//--------------------------------------------------------------------------
-
extern PACKAGE TForm1 *Form1;
//--------------------------------------------------------------------------
-
#endif




> >   t.x=thk.x*cos(angel)-thk.x*sin(angel)+thk.x;
> >   t.y=thk.y;
> >   t.z=thk.z*sin(angel)+thk.z*cos(angel)+thk.z;

> Try
>   t.x = thk.x*cos(angel) - thk.y*sin(angel) + thk.z;
>   t.y = thk.y;
>   t.z = thk.x*sin(angel) + thk.y*cos(angel) + thk.z;

> --
> Dave Eberly

> http://www.magic-software.com
> http://www.wild-magic.com

 
 
 

3d2dproblems

Post by Dave Eberl » Thu, 10 Jul 2003 14:52:33



> i can't understand why rectangel is flying away
> and can't understand why the variable angel is changed so strange
> may be somebody else know

The sin and cos functions expect *radians*, not *degrees*.

--
Dave Eberly

http://www.magic-software.com
http://www.wild-magic.com

 
 
 

3d2dproblems

Post by Tony Di Croc » Fri, 11 Jul 2003 01:58:56


If I understand you're problem, I think I did the exact same thing about 10
years ago... :)

I was rotating a 2d rectangle, and after a while it began to distort and
contort... Definatley not maintaing it's shape...

The problem is cause by a fundamental in programming that I have seen dozens
of times since, but never so visually...

                                                      -- Cumulative
Fractional Error --

I'm guessing that each frame you rotate you're points by 1 degree? And then
store the results of the rotations?

Instead, on the first frame rotate the original points by 1 degree, and
don't store the rotated points anywhere.
On the second frame rotate the original points by 2 degrees, and don't store
the rotated points anywhere.
On the third frame rotate the original points by 3 degrees, and don't store
the rotated points anywhere.

What is happening is that every time you do math ( multiplication or
division ) with a floating point variable the result is wrong by just a tiny
fraction... Because you are storing the results, and then rotating them
again, this error term builds up.

Get it?

Of course, their is always the possibility that I have mis-understood you're
question...

    Tony



> > i can't understand why rectangel is flying away
> > and can't understand why the variable angel is changed so strange
> > may be somebody else know

> The sin and cos functions expect *radians*, not *degrees*.

> --
> Dave Eberly

> http://www.magic-software.com
> http://www.wild-magic.com