2010. 12. 4. 02:10
Programing erlang p.71

Most effient way to make a list. Insert into a head.

some_function([H|T], ..., Result, ...) ->
   H1 = ... H ...,
   some_function(T, ..., [H1 | Result ], ...);
some_function([], ..., Result, ...) ->
   {..., Result, ...}.

Use function lists:reverse to reverse Result(list).
Don't use operation ++ (ex: List ++ [H])

programming erlnag p.168
-module(ctemplate).
-compile(exprot_all).

start() ->
   spawn(fun() -> loop([]) end).

rpc(Pid, Request) ->
   Pid ! {self(), Request},
   receive
      {Pid, Response} ->
            Response
   end.

loop(X) ->
   receive
      Any ->
        io:format("Received:~p~n", [Any]),
        loop(X)
   end.

Use TDD strategy.
Use erlang shell as small steps on TDD.
Posted by newpolaris
2010. 12. 3. 14:56

% module

-module(eulerPro2).
-export([piboSum/1]).
   
isEven(N) ->
    even(N rem 2 =:= 0).
even(false) -> odd;
even(true) -> even.

piboSum(N) ->
    piboSum({1,1},{0,N},odd).

piboSum({A,B},{Sum,N},odd) when A =< N ->
    piboSum({B,A+B},{Sum,N},isEven(B));

piboSum({A,B},{Sum,N},even) when A =< N ->
    piboSum({B,A+B},{Sum+A,N},isEven(B));

piboSum({A,_},{Sum,N},_) when A > N ->
    Sum.


          
% test
-module(eulerPro2_tests).
-include_lib("eunit/include/eunit.hrl").

piboSum_test() ->
    ?assertEqual(0, eulerPro2:piboSum(1)),
    ?assertEqual(2, eulerPro2:piboSum(2)),
    ?assertEqual(2, eulerPro2:piboSum(5)),
    ?assertEqual(10, equerPro2:piboSum(8)).

   

Posted by newpolaris
2009. 11. 14. 22:41
보통 책에서 나오는 다이얼로그 하나 나오고 닫기 해야만 넘어가는 히스토그램에서 벋어나고 싶다면?

왜 저자들이 일부로 그리했을까?

이유는
1. 닫기를 않하고 넘어가려면 모달리스 다이얼 로그를 만들어야 한다.
2. 그림 마다 다른 히스토그램을 그려야 할껀데 이거 처리하기 귀찮다.

결국 모든건 귀차니즘 때문이다.

자세히 들어가도록 하자.

다이얼로그는 2가지가 있다.
모달
모달리스

한넘은 모든 자원을 다 차지하고 닫기를 눌러야 넘어가 지는 모달
다른 하나는 다른 MDI 윈도우와 공존하는 모달리스 다이얼로그이다.

모달 다이얼로그의 코드는 흔히 많이 봤을꺼다.

// 간단하긔
dlg.DoModal() == IDOK

값을 받아올일 있을 때, Doc쪽에 잘 연결 시켜서 위에 한줄이면 된다.

그런데 모달의 경우는 하나가 다 자원 차지하고 지혼자 살다가 죽으면 되니 문제가 없지만
공존하려면?
함수 하나에서 저넘 수명이 끝나면 안되것지? 뒷처리도 해야하고

그렇기에 수명이 꽤 (아마 프로그램만큼) 긴 곳에 넣어두고 다른 MDI가 뒤에서 하고 있을 일을
우리가 직접 해주어야 한다.

진접 MDI 흉내는 귀찮으므로 우선 1개만 있다고 하자.

우선 모달리스 다이얼로그에 대해 간략히 3가지만 알아가자

1. 어딘가 선언하고
CWinApphitogramDlg *histodlg; // 그냥 늘 만드는 다이얼로그

2. new로 생성후 Create를 하자
this->histodlg = new hitogramDlg;
histodlg->Create(IDD_Histogram); //IDD_Histogram 늘 만드는 히스토 그램

3. 어디선가 종료전 이넘을 지우자
delete histodlg;



본인은

App에
//class CmyCVApp - 아마 여기 말고 MainFrame에 넣는게 옳지 않았을까 한다.
CWinApphitogramDlg *histodlg; // 그냥 늘 만드는 다이얼로그

int CmyCVApp::ExitInstance() // 속성에서 이 함수를 찾아서 더블클릭하면 알아서 만들고 연결해주니 편하다
{
delete histodlg;
}

BOOL CmyCVApp::InitInstance() // 이넘은 보통 생성되어 잇다.
{
    this->histodlg = new hitogramDlg;
    histodlg->Create(IDD_Histogram);
}

아래 처럼 했다.

이제 실제 Hitogram의 동작을 살펴보자.

// 단순한 외부 호출용 public DO함수
int CmyCVApp::ReNewHistogram(void)
{
    histodlg->ReNewHistogram();
    return 0;
}

int CmyCVApp::ShowHistowindow(void)
{
// 모달리스 다이얼로그는 아래 명령 1줄로 그릴수 있다.
    histodlg->ShowWindow(SW_SHOW);
    return 0;
}

// class CmyCVDoc 의 적절한 함수에 (Histogram을 뛰우는 함수 안이면 적절하겠져?)
CmyCVApp* pwinapp = static_cast<CmyCVApp*>(AfxGetApp());
pwinapp->ShowHistowindow();    

라고 두어 Hitogram 메뉴를 딱 누르면 히스토 그램이 뜨도록 했다.

이제 Hitogram의 그림은 어케 그릴까?


ReNewHistogram()
MDI에서 그림 창이 바뀜에 따라 히스토그램을 갱신하도록 했다.
그러한 작업은 View에서 속성에서 OnActiveView에 아래처럼 하게 하면 된다.
void CmyCVView::OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView)
{
    // TODO: 여기에 특수화된 코드를 추가 및/또는 기본 클래스를 호출합니다.
    CmyCVApp* pwinapp = static_cast<CmyCVApp*>(AfxGetApp());
    pwinapp->ReNewHistogram(); // MDI가 클릭되면 histogram renew함수를 호출하세여
    CScrollView::OnActivateView(bActivate, pActivateView, pDeactiveView); // MS 코드
}
//좀더 좋게 만들려면 그림 변화를 검사하도록 하거나(얼마안되는 계산량 절감)
//Doc에 Histogram을 만들어 놓고 알아서 갱신 하도록 하면 되것지?

ReNewHistogram 함수는
ActiveFrame의 Doc에 이미지를 찾아야하므로 몇단계를 밝아야하고
Doc가 만들어 질때도 호출되므로, 그림이 불려와질땐 호출되면 안되니 Null 검사를 한다.


// 속성에서 WM_PAINT 를 더블클릭하면  이 함수를 만들어 준다.
// WM_PAINT 즉 그림 다시 그릴때 오면 항상 호출
OnPaint()
단순히 어디서나 나오는 히스토그램 그리는 방법을 구현하거다

이러니 모달리스로 구현하지 않는다.
귀찮거든?






int hitogramDlg::ReNewHistogram(void)
{   
    CMainFrame *pFrame = (CMainFrame *)AfxGetMainWnd();
    CChildFrame *pChild = (CChildFrame *)pFrame->GetActiveFrame();
    CmyCVDoc *pDoc = (CmyCVDoc *)pChild->GetActiveDocument();
    if (pDoc == NULL) return -1;
    const BYTE * const * pImg = pDoc->MyImg.getImg2DPointer();
    const unsigned int sizeX = pDoc->MyImg.getX();
    const unsigned int sizeY = pDoc->MyImg.getY();
    // Set histogram
    memset(&histoImg, 0, 256*sizeof(float));

    for(int y =0; y < sizeY; y++)
    {
        for(int x =0; x < sizeX; x++)
        {
            int idx = pImg[y][x];
            // add one number
            histoImg[idx]++;
        }
    }

    // normalize
    int maxvalue = 0;
    for( int x = 0; x < 256; x++)
        maxvalue  = (maxvalue > histoImg[x]) ? maxvalue : histoImg[x];
    for( int x = 0; x < 256; x++)
        histoImg[x] /= maxvalue;

    InvalidateRect(NULL);
    return 0;
}


void hitogramDlg::OnPaint()
{
    CPaintDC dc(this); // device context for painting
    // TODO: 여기에 메시지 처리기 코드를 추가합니다.
    // 그리기 메시지에 대해서는 CDialog::OnPaint()을(를) 호출하지 마십시오.
   
    int nWidth = 1;
    COLORREF  m_color = RGB(255,0,0);
    CPen myPen(PS_SOLID, nWidth, m_color);
    CPen *pOldPen = dc.SelectObject(&myPen);

    // Draw histogram on dialog
    CRect rect;
    GetClientRect(&rect);
   
    int height = rect.Height() - 5;
    int width = rect.Width() - 5;

    for(int x =0; x < 256; x++)
    {       
        dc.MoveTo( int(x* width /256)+2, height - 5);
        dc.LineTo( int(x* width /256)+2, height*(1-histoImg[x]) -5);
    }
}

Note:

onActivateFrame()
onActivateView()
View는 MDI를 클릭할때마다 호출된다
Frame은 MDI를 클릭해도 호출이 안된다.

Posted by newpolaris
2009. 10. 26. 05:07
이미지도 0~255 까지라 BYTE고 mask도 BYTE로 하고 계속 코딩해나갔다.
BYTE Ymask[9] = { 1, 2, 1,
                             0, 0, 0,
                          -1, -2, -1};

실제 문제는

product.correlation(3, 3, Xmask, MyImg.getX(), MyImg.getY(),
                            MyImg.getImg2DPointer(), XSobel.getImg2DPointer());

여기서 터졌다.

for (int j=0; j < _iy; j++)
 {  
  for(int i=0; i< _ix; i++)
  {   
   int temp = 0;
   int idx = 0;
   for(int b=-py; b <= py; b++)
   {
    for(int a=-px; a <= px; a++)
    {  
     int hi = static_cast<int>(getV(j +b, i + a));
     int m = _mask[idx];
     temp += static_cast<int>(getV(j + b , i + a ) * _mask[idx++]);
    }
   }
   _after[j][i] = static_cast<BYTE>(temp);
  }
 }

무려 4중 for문.

코드를 보면 머 알겠냐? 로직은 문제 없는것 같고, 디버깅하다 하다 (딴대를 삽질 했음)

결국 보조 변수를 두고 보니. mask 값이 이상한것이다.

"어? warn L4에선 저런거 다 잡아 주는데?"

실제로 확인하니 언제 내가 바꾼건지. L3로 바껴져 있엇다.

오늘의 교훈:

C 시간에 int 자료형 크기 외운 프로그래머 심정을 알것다.

L4가 진리
1>c:\documents and settings\newpolaris\my documents\visual studio 2008\projects\mycv\mycv\mycvdoc.cpp(231) : warning C4245: '초기화 중' : 'int'에서 'BYTE'(으)로의 변환입니다. signed 또는 unsigned가 일치하지 않습니다.
1>c:\documents and settings\newpolaris\my documents\visual studio 2008\projects\mycv\mycv\mycvdoc.cpp(231) : warning C4245: '초기화 중' : 'int'에서 'BYTE'(으)로의 변환입니다. signed 또는 unsigned가 일치하지 않습니다.
1>c:\documents and settings\newpolaris\my documents\visual studio 2008\projects\mycv\mycv\mycvdoc.cpp(231) : warning C4245: '초기화 중' : 'int'에서 'BYTE'(으)로의 변환입니다. signed 또는 unsigned가 일치하지 않습니다.

그 1억짜리 코드 체크기 안살꺼면 L4하고 ms 코드 체커기 돌려 (따른거 없나?)

결과: 열심히 삽질중. 쓸만한건 못건져
1>C/C++ 코드 분석을 실행하고 있습니다...
1>c:\documents and settings\newpolaris\my documents\visual studio 2008\projects\mycv\mycv\cfourier.cpp(111) : warning C6211: 예외로 인해 'pSpectrum' 메모리 누수가 발생하고 있습니다. 로컬 catch 블록을 사용하여 메모리를 정리하십시오.: Lines: 105, 107, 109, 111, 112, 114
1>c:\documents and settings\newpolaris\my documents\visual studio 2008\projects\mycv\mycv\cfourier.cpp(167) : warning C6211: 예외로 인해 'pPhase' 메모리 누수가 발생하고 있습니다. 로컬 catch 블록을 사용하여 메모리를 정리하십시오.: Lines: 157, 159, 161, 167, 168, 170
1>c:\documents and settings\newpolaris\my documents\visual studio 2008\projects\mycv\mycv\cfourier.cpp(388) : warning C6211: 예외로 인해 'tr' 메모리 누수가 발생하고 있습니다. 로컬 catch 블록을 사용하여 메모리를 정리하십시오.: Lines: 386, 388, 389
1>c:\documents and settings\newpolaris\my documents\visual studio 2008\projects\mycv\mycv\quantizelevel2.cpp(59) : warning C6246: 'nPos'의 지역 선언이 외부 범위에 있는 같은 이름의 선언을 숨깁니다. 자세한 내용은 줄 '54'('c:\documents and settings\newpolaris\my documents\visual studio 2008\projects\mycv\mycv\quantizelevel2.cpp')에 있는 이전 선언을 참조하십시오.: Lines: 54
1>c:\documents and settings\newpolaris\my documents\visual studio 2008\projects\mycv\mycv\dib.cpp(690) : warning C6011: NULL 포인터 'lpbi'을(를) 역참조하고 있습니다.: Lines: 667, 668, 669, 672, 675, 678, 679, 686, 687, 689, 690
1>c:\documents and settings\newpolaris\my documents\visual studio 2008\projects\mycv\mycv\cmyfourier.cpp(132) : warning C6211: 예외로 인해 '_Re' 메모리 누수가 발생하고 있습니다. 로컬 catch 블록을 사용하여 메모리를 정리하십시오.: Lines: 128, 132, 133
1>c:\documents and settings\newpolaris\my documents\visual studio 2008\projects\mycv\mycv\cmyfourier.cpp(333) : warning C6001: 초기화되지 않은 메모리 'y'을(를) 사용하고 있습니다.: Lines: 308, 310, 312, 314, 326, 328, 329, 333
1>c:\documents and settings\newpolaris\my documents\visual studio 2008\projects\mycv\mycv\cmyfourier.cpp(334) : warning C6001: 초기화되지 않은 메모리 'x'을(를) 사용하고 있습니다.: Lines: 308, 310, 312, 314, 326, 328, 329, 333, 334
1>c:\documents and settings\newpolaris\my documents\visual studio 2008\projects\mycv\mycv\cmyfourier.cpp(336) : warning C6001: 초기화되지 않은 메모리 'w'을(를) 사용하고 있습니다.: Lines: 308, 310, 312, 314, 326, 328, 329, 333, 334, 333, 334, 333, 334, 336
1>c:\documents and settings\newpolaris\my documents\visual studio 2008\projects\mycv\mycv\cmyfourier.cpp(369) : warning C6211: 예외로 인해 '_tempIm' 메모리 누수가 발생하고 있습니다. 로컬 catch 블록을 사용하여 메모리를 정리하십시오.: Lines: 367, 369, 370
1>코드를 생성하고 있습니다...
1>c:\documents and settings\newpolaris\my documents\visual studio 2008\projects\mycv\mycv\cmyfourier.cpp(337) : warning C4701: 초기화되지 않았을 수 있는 'w' 지역 변수를 사용했습니다.
1>c:\documents and settings\newpolaris\my documents\visual studio 2008\projects\mycv\mycv\cmyfourier.cpp(334) : warning C4701: 초기화되지 않았을 수 있는 'x' 지역 변수를 사용했습니다.
1>c:\documents and settings\newpolaris\my documents\visual studio 2008\projects\mycv\mycv\cmyfourier.cpp(333) : warning C4701: 초기화되지 않았을 수 있는 'y' 지역 변수를 사용했습니다.
1>c:\documents and settings\newpolaris\my documents\visual studio 2008\projects\mycv\mycv\cmyfourier.cpp(337) : warning C4701: 초기화되지 않았을 수 있는 'z' 지역 변수를 사용했습니다.
1>빌드 로그가 "file://c:\Documents and Settings\newpolaris\My Documents\Visual Studio 2008\Projects\myCV\myCV\Debug\BuildLog.htm"에 저장되었습니다.














 
Posted by newpolaris
2008. 6. 24. 18:30

void Canvas::moveTo(const float x, const float y)
{
 CP.set(x, y);
}

void Canvas::moveTo(const Point2& pt)
{
 moveTo(pt.getX(), pt.getY());
}

1>i:\study\opengl\canvas\canvas\canvas.cpp(31) : error C2662: 'Point2::getY' : 'this' 포인터를 'const Point2'에서 'Point2 &'(으)로 변환할 수 없습니다.
1>        변환하면서 한정자가 손실됩니다.
1>i:\study\opengl\canvas\canvas\canvas.cpp(46) : error C2662: 'Point2::getY' : 'this' 포인터를 'const Point2'에서 'Point2 &'(으)로 변환할 수 없습니다.
1>        변환하면서 한정자가 손실됩니다.


What the hell??

const float Point2::getY() { return y;}
상수화된 const Point2& pt
그걸 쓰는 pt.getX(); <= 이분은 상수화 되어야 한다.

고러 const float Point2::getY() cont { return y;} 가 되면 문제 없다.

안하던 const 선언 하려이 에러 투성이




Posted by newpolaris
2008. 6. 24. 18:23

Turtle graphic 은 우리가 지금 어디있는지 (좌표)는 신경 안쓰고
전진, 방향 회전 단 이 2개 함수로 구현되는 그림을 말합니당
cvs.forward(L, 1);
cvs.turn(89.5);
L 길이 만큼 전진하는데 선을 그린다 (1), 선을 그리지 않는다 (0)
회전 89.5도 입니다
물론 실제로 선 그리는건 vertex2f(x,y) 이기 때문에
현제 바라보는 각도, 현제 절대 좌표 위치 기록을 위한 CD, CP를 둬야하고요;

마치 볼펜 하나 들고 흰 종이에 이어 그린다 라고 생각하시면 편해요(??)

void Canvas::turn(float angle)
{
 CD+=angle;
}

void Canvas::forward(float dist, int isVisible)
{
 const float RadPerDeg=0.017453373;
 float x = CP.getX() + dist * cos(RadPerDeg * CD);
 float y = CP.getY() + dist * sin(RadPerDeg * CD);
 if(isVisible)
  lineTo(x, y);
 else moveTo(x, y);

 CP.set(x, y);
}

아래 그림은 한선을 그린후 89.5도로 계속 회전하면서 선길이를 0.1씩 늘린 모양입니다.

사용자 삽입 이미지






















 float L = 1;
 for(int i=0; i<500; i++)
 {
  cvs.forward(L, 1);
  cvs.turn(89.5);
  L += 0.1;
 }

위 그림 같은 것도 그릴 수 있고여
-144도면 오각 별이 그려 집니다.

또 정 n 각형도 각도 계산 해서 하면 간단합니다.




이번엔 Rosette 란걸 그려 봅시당 turtle graphic과는 별 관련 없어요
각점을 연결 시켜야 하기에 위의 turtle graphic과는 달리 각점을 저장해야 합니당

사용자 삽입 이미지
























N = 5;
사용자 삽입 이미지
























N = 25;
void Canvas::Rosette(int N, float cx, float cy, float radius, float rotAngle)
{
 const float PI = 3.14159265;
 Point2 pt[100]; // 정 100각형 까지

 if(N<3) return; // 2개 짜리 도형은 없음

 double angle = rotAngle *  PI/ 180; // initial angle
 double angleInc = 2* PI / N;  // angle increment

 // 정 N 각형 좌표 위치를 찾는다.
 for(int k = 0; k<=N; k++)
 {
  angle += angleInc;
  // 각 N 각형의 각 점의 위치를 기억한다.
  pt[k].set(radius * cos(angle) + cx, radius * sin(angle) + cy);
 }

 // 각점을 연결한다.
 for(int i =0; i < N-1; i++)
  for(int j = i+1; j<N; j++)
  {
   moveTo(pt[i]);
   lineTo(pt[j]);
  }
}

==================================================================================================
void Canvas::moveTo(const float x, const float y)
{
 CP.set(x, y);
}

void Canvas::moveTo(const Point2& pt)
{
 moveTo(pt.getX(), pt.getY());
}

void Canvas::lineTo(const float x, const float y)
{
 glBegin(GL_LINES);
  glVertex2f((GLfloat)CP.getX(), (GLfloat)CP.getY());
  glVertex2f((GLfloat)x, (GLfloat)y);
 glEnd();
 CP.set(x, y);
 glFlush();
}

void Canvas::lineTo(const Point2& pt)
{
 lineTo(pt.getX(), pt.getY());
}

Posted by newpolaris
2008. 6. 24. 16:29
=> 한부분만 계속 보고 있지말고 한 단계식 뒤로 살펴보자
고대 이스라엘 때의 일이다. 어떤 군사령관에게 연락 병이 급히 당도하여 주요한 요새를 적에게 빼앗겼다고 보고하였다. 군사령관은 몹시 화가 나 눈에 쌍심지를 돋구고 있었다. 그러자 부인이 사령관의 방으로 불러들여 말하였다.

[나는 지금 당신보다 더 안좋은 일을 당했어요.]
[대체 그게 무슨 말이오?]
[당신 표정에서 당신의 당황한 기색을 읽을 수 있어요. 요새야 다시 싸워 빼앗으면 되지 않아요. 하지만 사령관인 당신이 용기를 잃는다면 그것은 군대 전부를 잃는 것보다 훨씬 더 위험한 것입니다.]

사용자 삽입 이미지



















위의 그림은 정답이 아니당

사용자 삽입 이미지



















이게 정답이다 머가 잘못된걸까?

 cvs.forward(3 * 1, 1);
 cvs.turn(90);
 cvs.forward(1, 1);
 cvs.turn(90);
 cvs.forward(1, 1);
 cvs.turn(90);

문제의 로직부분

1st 혹시 각도 부분을 담당하는 CD 부분이 저장않되는게 아닐까?
    -> cvs.forward(5, 1); 길이가 늘어났다;

??
 float x = CP.getX() + dist * cos(RadPerDeg * CD);
 float y = CP.getY() + dist * cos(RadPerDeg * CD);
붙여넣기의 폐해

이번건 무척 간단하지만 복잡해지면 노다가 밖에 없다.
test 기반 계발
코드 리뷰


Posted by newpolaris