C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 팁&트릭
C++Builder Programming Tip&Tricks
[676] Canvas 좌표계 바꾸기
장성호 [nasilso] 8149 읽음    2007-07-20 16:12
TCanvas 및 Window의 기본 좌표는  좌측상단에서 ( 0,0 )  부터 시작됩니다.
그러니까 Y좌표가 위에서 아래로 내려옵니다.
근데 이게 때로 불편할때가 많습니다.

그래서 간단히 Y좌표계를 reverse 시킴으로서
좌측하단이 ( 0 , 0 ) 이 되도록 해서 사용하고자 합니다.

- TCanvas를 이용해구요
- TCanvas를 상속받아 새로운 클래스를 만듭니다.



[새로운 클래스]
class TScaleCanvas : public TCanvas
{
        int H; //DC의 높이
public:
       void __fastcall LineTo(int X, int Y);
       void __fastcall MoveTo(int X, int Y);
       void __fastcall Rectangle(int X1, int Y1, int X2, int Y2)/* overload */;
       void __fastcall Rectangle(TRect rc)/* overload */;
     __fastcall ~TSCaleCanvas()
     {
        if(Handle)DeleteDC(Handle);
     }
};
//----------------------------------------------------


[오버라이딩 함수들]
void __fastcall TSCaleCanvas::MoveTo(int x,int y)
{
    TCanvas::MoveTo(x,H-y);
}
void __fastcall TSCaleCanvas::LineTo(int x,int y)
{
    TCanvas::LineTo(x,H-y);
}
void __fastcall TSCaleCanvas::Rectangle(int x1,int y1,int x2,int y2)
{
    TCanvas::Rectangle(x1,H-y1,x2,H-y2);
}
void __fastcall TSCaleCanvas::Rectangle(TRect rc)
{
    rc.top=H-rc.top;
    rc.bottom=H-rc.bottom;
    TCanvas::Rectangle(rc);
}

//============================================================================

// 사용하기
void __fastcall TForm1::Button1Click(TObject *Sender)
{

   TSCaleCanvas *sCan=new TSCaleCanvas;
   sCan->Handle=GetDC(Panel1->Handle);      // TPanel Canvas에   Draw
   sCan->H=Panel1->Height;
   sCan->MoveTo(10,10);
   sCan->LineTo(100,100);
   sCan->Rectangle(100,100,200,200);
   sCan->Rectangle(Rect(200,200,250,250));
   delete sCan;

}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
   TSCaleCanvas *sCan=new TSCaleCanvas;
   sCan->Handle=Image1->Canvas->Handle;     // TIamge Canvas 에 Draw
   sCan->H=Image1->Height;
   sCan->MoveTo(10,10);
   sCan->LineTo(100,100);
   sCan->Rectangle(100,100,200,200);
   sCan->Rectangle(Rect(200,200,250,250));
   delete sCan;
}
//---------------------------------------------------------------------------

제대로 동작하려면 TCanvas의 다른 함수들도 위와같이 구현해서 써야 됩니다.

컴퓨터 프로그램하면서 이제는 Y 좌표가 위에서 아래로 내려오는게 많이 익숙하지만

아직도 노트에 그래프 그려서 분석할때는 Y좌표가 아래서 위로 올라가게 그려놓습니다.

별것 아니지만 저렇게 간단히 만들어 쓰면...

편리할 수 있을것입니다.

초보자용 날 팁 이었습니다.
김태선 [cppbuilder]   2007-07-20 17:28 X
재미있는 아이디어군요.
이런식으로 해도 될것 같습니다.
//---------------------------------------------------------------------------

class TScaleCanvas : public TCanvas
{
public:
    void __fastcall LineTo(int x, int y)
    {
        TCanvas::LineTo(x, ClipRect.Height()-y);
    }
    void __fastcall MoveTo(int x, int y)
    {
        TCanvas::MoveTo(x,ClipRect.Height()-y);
    }
    void __fastcall Rectangle(int x1, int y1, int x2, int y2)
    {
        TCanvas::Rectangle(x1,ClipRect.Height()-y1,x2,ClipRect.Height()-y2);
    }
    void __fastcall Rectangle(TRect rc)
    {
        rc.top=ClipRect.Height()-rc.top;
        rc.bottom=ClipRect.Height()-rc.bottom;
        TCanvas::Rectangle(rc);
    }
};
//----------------------------------------------------
// 사용하기

void __fastcall TForm1::Button1Click(TObject *Sender)
{
   TScaleCanvas* sCan = (TScaleCanvas*)Canvas;
   sCan->MoveTo(10,10);
   sCan->LineTo(100,100);
   sCan->Rectangle(100,100,200,200);
   sCan->Rectangle(Rect(200,200,250,250));
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
   TScaleCanvas* sCan = (TScaleCanvas*)Image1->Canvas;
   sCan->MoveTo(10,10);
   sCan->LineTo(100,100);
   sCan->Rectangle(100,100,200,200);
   sCan->Rectangle(Rect(200,200,250,250));
}
//---------------------------------------------------------------------------

void __fastcall TForm1::BitBtn1Click(TObject *Sender)
{
   TScaleCanvas *sCan=new TScaleCanvas;
   sCan->Handle=GetDC(Panel1->Handle);      // TPanel Canvas에 Draw
   sCan->MoveTo(10,10);
   sCan->LineTo(100,100);
   sCan->Rectangle(100,100,200,200);
   sCan->Rectangle(Rect(200,200,250,250));
   delete sCan;
}
//---------------------------------------------------------------------------
장성호 [nasilso]   2007-07-20 17:46 X
ClipRect을 몰라서...

근데 아래에 InputQuery에 문제내 놓은것
답변안달아주실꺼예요?
김태선 [cppbuilder]   2007-07-20 18:14 X
헠.... 놀람모드.
장성호 [nasilso]   2007-07-20 18:16 X
class 에 H를 property로 만들어 두면 쬐금더 간단할듯

class TScaleCanvas : public TCanvas
{
private:
       int __fastcall TSCaleCanvas::GetHeight()
public:
        // 생략
    __property int H = {read=GetHeight};

};
//---------------------------------------------------------------------------
int __fastcall TSCaleCanvas::GetHeight()
{
    TRect rc;
    GetClipBox(this->Handle, &rc);
    return rc.Height();
}
//---------------------------------------------------------------------------
void __fastcall TSCaleCanvas::LineTo(int x, int y)
{
    TCanvas::LineTo(x, H-y);
}


빨리 아랫쪽에 답변달아 줘요~~~!
김태선 [cppbuilder]   2007-07-20 18:46 X
멋진 방법이군요. ^^;

+ -

관련 글 리스트
676 Canvas 좌표계 바꾸기 장성호 8149 2007/07/20
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.