퇴근5분전

 전에 그래프 그리고 할때는 임의 점에서 각으로 특점 점을 찍어서 그렸던게 대부분이었는데... 

요즘 프로그램 업데이트를 위해 필요한걸 만들려다보니.. 이런 화살표가 필요한데... 

기본 pen에 있는 화살표는... 너무 작게 보인다. 그래서 선을 직접 그리는 걸로 만들려고... 간단히 

테스트 겸해서 만들어봤다. 

 

 몇년만에 다시 삼각함수를 ... 

1. pt1 찍고 -----------> pt2 까지 마우스로 움직였을때의 각( angle )을 구하고

2. 이 각에서 -25도, + 25도 되는 80의 거리를 가진 지점 위치를 구한다. 

3. 각각 구해진 자리를 pt1과 이어지도록 그린다. 

 

# 구성 

  - 판넬 하나 놓고. 

  - 판넬에 이벤트 paint, mouse_down, mouse_move, mouse_up 을 걸어준다. 

 

 public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        } 

        Pen linePen = new Pen(Brushes.Black, 2f) { 
            StartCap = System.Drawing.Drawing2D.LineCap.NoAnchor,
            EndCap = System.Drawing.Drawing2D.LineCap.NoAnchor,
        };

        private void panel1_Paint(object sender, PaintEventArgs e)
        {
            if (pt1 == pt2) return;

            e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            e.Graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
            e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

            e.Graphics.DrawLine(linePen, pt1, pt2);

            float angle = -CalcAngleDegree(pt1, pt2);
            Point arowPt1 = CalcAngleRotate(angle - 25f, new Point(80, 0));
            Point arowPt2 = CalcAngleRotate(angle + 25f, new Point(80, 0));

            e.Graphics.DrawLine(linePen, pt1.X, pt1.Y, pt1.X + arowPt1.X, pt1.Y + arowPt1.Y);
            e.Graphics.DrawLine(linePen, pt1.X, pt1.Y, pt1.X + arowPt2.X, pt1.Y + arowPt2.Y);
        }


        bool isMDn = false;
        Point pt1;
        Point pt2;
        private void panel1_MouseDown(object sender, MouseEventArgs e)
        {
            isMDn = e.Button == MouseButtons.Left;
            pt1 = pt2 = e.Location;
        }

        private void panel1_MouseMove(object sender, MouseEventArgs e)
        {
            if (isMDn)
            {
                pt2 = e.Location;
                panel1.Invalidate();            
            }
        }

        private void panel1_MouseUp(object sender, MouseEventArgs e)
        {
            if (isMDn) panel1.Invalidate();

            isMDn = false;
          //  pt1 = pt2 = Point.Empty;
        }
         

        public float CalcAngleDegree(Point p1, Point p2)
        {
            double theta = 0d;
            int a = p2.X - p1.X;
            int b = p2.Y - p1.Y;


            if (b < 0)
            {
                theta = - (180 / Math.PI * Math.Atan2(b, a));
            }
            else
            {
                theta = 180 + (180 - (180 / Math.PI * Math.Atan2(b, a)));
            }
            return (float)theta;
        }

        public Point CalcAngleRotate(float anlge, Point p1)
        {
            Point p2 = p1;
            double rad = Math.PI / 180 * anlge;
            double x2 = Math.Cos(rad) * p1.X - Math.Sin(rad) * p1.Y;
            double y2 = Math.Sin(rad) * p1.X + Math.Cos(rad) * p1.Y;
            return new Point((int)x2, (int)y2);
        }
    }

 

############# 간만에 삼각함수를 하려니... 또 헷갈리네.. 

변환 : 라디안 <----> 각

 

라디안 = PI / 180 * 각도;   

각 = 180 / PI * 라디안; 

 

라디안을 구하고 싶으면 PI로 시작하면 편함. 

각을 구하고 싶으면 180으로 시작하면 편함. 

 

------------------------------------------- 구글링하면 많이 나오니까.. 

두 지점의 pt1, pt2의 각을 구할때는 atan2를 쓴다. 

tan@ = 높이(b)/ 밑변(a);

@ = aTan2( b / a);

 

CalcAngleDegree : 두 지점간에 각도 구하기

CalcAngleRotate : 회전시켜 다른 지점 구하기( 화살표 머리 양쪽지점 )

 

소스도 간단하니 딱히 더 주석달게 없네...

 

총 18개 ( 3개는 허접하기도 하고 별기능 없는것이라 비공개 )

 

 이것으로 172개의 플젝 중에 선별해서 GitHub에 올릴 수 있는건 다 올렸다.

16년간 프로젝트 뛰면서 짬을 내서 만든 것중에 15개가 선별되었네. 꽁꽁 숨겨놨던건데... 이제서야 올렸네...

 실력 좋은 사람들이 만들어내는 코드 같은게 아니니... 꽁꽁 숨겨왔는데... 너무 급하게 막 올렸나? 싶기도 하고..

닷넷을 더 할 수 있을까? 자바로 가야 하나? 자바에서 써주려나?

난감한 문제네... 

 

GIT 관련...

# 1) 프로그래밍2022. 10. 26. 22:10

 친구에게 git관련 도움을 받았다. 

종일 관리 프로그램 소스를 github에 올리고 git개념 가이드만 겨우 봤네... 

저녁마다 차례로 봐야 할듯... 

github에 총 12개를 올렸다. 앞으로 3개나 4개쯤 더 올라가면 대충 될 것 같다. 

170여개의 프로젝트 파일중에 오픈소스 불러온 것들 40여개 정도 빼고, 올려도 될만한 것들을 고르는게 쉽지 않네... 

만들다 기능확인 하고 디자인이 구려서 또는 다른 프로젝트로 시간을 뺏겨서... 등등...

흔적만 남기고 멈춰버린 개발프로젝트가 많이 있네...

 

 - SVN만 써본 나에게 알려준 슬라이드쉐어( 간만에 들어와 보네.. )

svn 능력자를 위한 git 개념 가이드 (slideshare.net)

 

svn 능력자를 위한 git 개념 가이드

사내 공유를 위해 제작한 문서입니다만, 혹시 도움이 되실 분이 있을까 싶어서 공유합니다. 혹여 오류가 있을 수 있습니다. 관대한 마음으로 이해 부탁드리며 글 남겨주시면 참고하여 수정하겠

www.slideshare.net

 

: https://fork.dev/

 

Fork - a fast and friendly git client for Mac and Windows

Fork - a fast and friendly git client for Mac and Windows

fork.dev

 

브랜치배우기 : https://learngitbranching.js.org/?locale=ko

 

Learn Git Branching

An interactive Git visualization tool to educate and challenge!

learngitbranching.js.org

 

브랜치 전략 : http://blog.hwahae.co.kr/all/tech/tech-tech/9507/?popular=9507

 

Git 브랜치 전략 수립을 위한 전문가의 조언들 – 화해 블로그 | 기술 블로그

Git 브랜치 전략 효과적으로 VCS를 사용하려면 프로젝트 여건에 어울리는 브랜치 전략을 세워야 합니다. 이를 위한 첫 번째는 바로 브랜치 전략에 대한 비교 분석입니다. Git기반으로 워크플로우

blog.hwahae.co.kr

 

그리고 친구가 건낸말

fource push 만 조심해

force push 할 일이 별로 없긴한데 rebase 좋아하는 분들이 가끔 지 피쳐브랜치에 날려야할걸 실수로 다른데 날리지

그래서 rebase 금지인 팀도 있음

https://git-scm.com/book/ko/v2/Git-%EB%B8%8C%EB%9E%9C%EC%B9%98-Rebase-%ED%95%98%EA%B8%B0

 

Git - Rebase 하기

Rebase는 기존의 커밋을 그대로 사용하는 것이 아니라 내용은 같지만 다른 커밋을 새로 만든다. 새 커밋을 서버에 Push 하고 동료 중 누군가가 그 커밋을 Pull 해서 작업을 한다고 하자. 그런데 그 커

git-scm.com

 

땡큐~ 

 

밤에 만들어보았다.

 

A* 알고리즘 만든 소스 객체들을 재사용해서 금방 만들어졌다.

 

구글링 해도 색칠하는 알고리즘은 많이 나오는데... 길찾기 알고리즘은 설명이 거의 없다.

 

유튜브로 영상들만 있다. 영상 참고해서 대충 비스므리하게 만들어서 이게 정말 맞는건지는 모르겠지만...

 

길찾기는 잘 된다.

 

 # 단순하게 테스트.

 

 

 # 좀더 복잡하게... 맵을 만들어봤음.

 

각 Cell안에 방향을 나타내는 열거형 변수가 있어서 셀계산할때 방향을 계산하여 가지고 있게된다.

 

도착점(노란색)을 검색하면 도착점에서부터 방향을 역으로 찾아서 이동한다.

 

소스파일(숨겨짐)

 

길찾기 알고리즘 공부삼아 만들어봄.

 

https://www.redblobgames.com/pathfinding/a-star/introduction.html

https://qiao.github.io/PathFinding.js/visual/

http://itmining.tistory.com/66

http://blog.naver.com/PostView.nhn?blogId=denoil&logNo=221014139704 ( G값 계산에 대한 설명 )

 

여러 사이트 검색하다가 위 세개를 보고 몇일 파악하고 만듬.

 

 

동작은 잘되는 것은 봤는데...

 

세번째 링크 블로그에 탐색관련 설명중에...

 

3. 인접한 사각형이 이미 '열린 목록'에 있다면 해당 사각형의 비용이 더 좋은지 확인합니다. 즉,선택한 사각형과 비교하여 G점수가 어떤 것이 더 낮은지 확인 합니다. 그렇지 않으면 아무것도 하지 않습니다. 하지만 해당 사각형의 G 비용이 더 낮은 경우 인접 사각형들의 부모를 새로운 사각형으로 바꿉니다. 마지막으로, 그 사각형의 F와 G를 다시 계산합니다. 어렵다면 아래의 실제 작업 과정을 봐주세요.

출처: http://itmining.tistory.com/66 [IT 마이닝]

 

이게 뭔말인지 도저히 모르겠다. 만든걸 스탭별로 확인해봐도 ... 이전노드  대상을 가리키는 화살표라든가 재 계산된 G값이 달라 ...?

 

소스가 잘 못 만들어졌는지 테스트를 해보곤 있는데... 잘되는것 같은뎅..

 

쭉 다시 읽어보고 작업했는데 더 이상해... ( 아무리 해봐도 블로그에 있는 것처럼 안되네... )

 

 

 단, 대각선 <-- 을 지나가게 되어 있어서...

 

 

 

 

 

이렇게 대각선도 찾아간다... 흠...

 

두번째 링크에꺼로 해보면

 

요렇게 비해서 검색을 하네??

 

 

 

일단 이거 수정하고 나면 Flood Fill Path Find 라는 방법으로 해보려고 한다.

음 더 간단해보여서..?

 

소스(숨겨짐)

 

###################################################################################

드디어 고쳤다.

 

 인접한 셀(B)이 검색대상에 이미 있는 거면

현재중심셀(A)을 이용하여 인접한셀(B)의 G값을 임시로 계산해서

인접한 셀(B)의 원래 G값과 임시로 계산한 G값과 비교해서 

임시로 계산한 G값이 작으면 인접한 셀(B)의 이전노드셀을 현재중심셀(A)로 지정한다.

 

 

 

 

 

훈스닷넷에 질문 : http://www.hoons.net/Board/QACSHAP/Content/85519

제목 : string이 아닌 String Array 한번에 파싱하는 방법이 혹시 있나요?

 

음. 10000개나 20000개 정도 늘어나면 느리다??

 

왜 느리지 하고... 만들어봤더니..

 

 const int max_length = 20000;
            string[] val = new string[max_length];

            for (int loop = 0; loop < max_length; loop++)
            {
                val[loop] = string.Format("a{0}, b{0}, c{0}, d{0}", loop);
            }

            Stopwatch sw = new Stopwatch();
            sw.Reset();
            sw.Start();
            string[] rst = new string[val.Length];
            for (int loop = 0; loop < max_length; loop++)
            {
                string[] tmp = val[loop].Trim().Split(',');
                if (tmp.Length > 1)
                    rst[loop] = tmp[1];
            }
            sw.Stop();
            this.Text = "" + sw.ElapsedMilliseconds.ToString("N0");

 

 

10000개 일때 7ms,  20000개 일때 24ms ... 겁나 빠른데...

 

느려지는 건 뭘까? 질문에서의 데이타가 다른거 겠지? 또는 어떤 대상과 비교했을때 느리다고 보는건가?

 

심심해서 잠깐... 해봤다.

 

 

 프리단가도... 이런건 정직들시켜서 했음 좋겠다...

 

C1FlexGrid가 꾀 예전 버젼이고 Winform 컨트롤이다.

 

 이 그리드를 이용해서 트리를 만들고 간단하게 트리 노드들을 관리하도록 만들기 위해

방법을 하나 생각하고 개발에 들어갔다.

 

트리는 굉장히 쉽게 만들어진다.

 fxGrid.Tree.Column = 컬럼 인덱스;

 

각 Row별로 레벨값만 주면

 Row r = fxGrid.Rows[ rowIndex ];

 r.IsNode = true;

 r.Node.Level = 레벨값;

 

그런데 이 트리에 입력값과 level값 핸들링 상하 이동처리가 번거롭다.

기존 방식으로 1개의 Row를 등록하고 상위 코드를 따다가 적재하고 자기 코드 생성하고... 등등... 귀찮다.

 

엑셀이나 메모장으로 데이타 대상을 몽땅 복사해서 그리드에 붙여넣기를 한다.

 

그리고 조정이 필요한 행들을 선택해서 Ctrl + {왼쪽, 오른쪽} 은 level을 앞 뒤로 조정해주고,

Ctrl + {위, 아래} 는 Row를 위로 아래로 이동시켜준다.

 

이때 필요한 것이!!! 전체 노드에 대하여 코드와 상위코드에 대한 정보 업데이트이다.

 

처음에 성공했다고 생각했는데... 자세히 코드를 보니 코드들이 어긋나있었다.

 

그래서 오후 내내 3시간 삽질을 했는데 ... 안되서 스트레스만 받고 퇴근!

 

지하철에서도 알고리즘을 고민해봤는데... 안되서 ㅠㅠ;

 

7시 반에 와서 9시반에 성공했으니 나름 2시간 동안 고생한 보람은 있네.

 

가장 중요한 힌트가 된 것은 스택이란 자료구조!

 

*** 작업 전 고려했던 내용.

 - 기존에 내 프레임웍 코드에 사용했던 메뉴 트리처럼 생각하고 시작했었음.

      #메뉴1lv

      ##메뉴2lv

      ###메뉴3lv   ( cd, ucd 관련해서 알고리즘 고려를 못한것이 스트레스의 발단이 됨... )

 - 다수의 일괄 편집!

 - 관리의 편의성! ( 새 노드 추가, 삭제, 이동 등... )

 - 나이스에서 했던 메뉴관리 트리 처럼 생각... ( 컨트롤 제작회사가 달라서 그런지 완전 다름 )

 

### 최초 상태 Level +를 누르면 CD와 UCD를 지정된 포멧으로 생성해준다.

 

### 트리 구조로 바꾼 결과

 

생성되는 코드를 포멧을 지정해서 만들 수 있다는 장점.

 

한번에 여러건의 입력이 가능하다는 장점.

 

단점. 많은 양에 대해 안해봐서 퍼포먼스를 예측 할 수가 없다는 것. ( 해봐야 알듯함: 출근하면 5만건 정도 생성해서 해봐야 겠음. )

 

 

 

 

WPF 의 WindowsFormHost 로 Winform Control을 올렸을때

ScrollViewer를 추가하였을때 스크롤이 발생하면 호스팅되는 컨트롤이 WPF컨트롤을 덮어버리는 현상...

 

  찾다보니 안재우님 블로그에서 발견한 http://www.rsdn.ru/forum/dotnet.gui/3740163.1.aspx 

 이건 몇년전 프로젝트에서 적용해서 잘 사용하였다.

 

 그러나 이번 Windows 10 업그레이드를 하면서 위 화면이 깨진다.

DPI 96 ( 100% ) 일때는 괜찮지만 125% 일때 깨지는데...!!!!

 

이걸 이번에 내 노트북을 업그레이드 해서 디버깅해서 잡았다.

 

쉽지 않은데... 이거 골때리게 잡았음!!

 

버그인듯함.

 

 

 

 이번엔 연말정산 관련 프로그래밍을 어쩌다 떠안았다.

 

1. 일단 라이브러리를 이용하여 테스트.pdf 파일에서 xml을 추출!

 

2. 이 xml을 대상으로 개발하는 것이었다.

 

3. xml을 visual studio에서 class 로 만듬.

 

4. 만들어진 class 객체를 한번 더 정제함  

   private 타입 변수;

   public 타입 변수 { get ... }

  형태를 프로퍼티만 있게 수정. ( + 각 프로퍼티별 주석문 추가 )

 

5. 각 양식별 ( A101Y, B101Y... )로 랩핑클래스 작성.

 

간략이 적어보면 이런 내용인데...

 

좀 거지 같은게 pdf로 국세청 홈페이지로 xml 타입정의서나 서식정보, 각 필드에 대한 상세설명서등이 제공되니까.

 

엑셀이었으면 그냥 복사해서 편집하면 되는데... pdf라 ㅡ.,ㅡ;;;

pdf 내용을 클립보드에 복사해서 이걸 파싱하는 프로그램만들어서 1차 정제해서 excel에 붙여넣기 ... 반복해서 데이타를 엑셀로 옮겼다. ㅡ.,ㅡ;;

 

일단 받은지 하루만에 DB저장 전까지는 마쳤다.

 

자세한 기록은 생략...

 

국세청에서 양식정보를 엑셀로 제공하였음 좋았을텐데 ㅡ.,ㅡ;;; 오피스 사용료때문일까나?

  >>> PDF 를 직접 열어서 pdf의 내용을 선택하고 우측버튼에 복사, 서식포함 복사가 있더라...

 

 

Dic.xlsx < 연말정산 xml attribute와 각 설명 pdf에서 추출한 내용 : 2.전자문서_XML_정의서(공제신고서)_20160114.pdf  >

 

  * 누락여부는 눈으로 대략 확인한것이므로... 사용시 주의가 필요함!!!

 

위 내용은 공제신청서? 란걸 처리 할때 란다...

 

사용자가 입력하는 업로드와 관련된 xml양식은 깊이 감춰져 있는 것 같음.

 

 

 오늘 양식을 다시 받았다. 한참을 찾았네...

국세청 홈택스에 사업자로 로그인하여 들어가야 다운로드가 되는 듯...

 

<홈텍스에 들어가서 스샷>

 귀속 전자문서 XML, SAM 정의서가 해당 양식이었다.

그래서 집에서 비쥬얼 스튜디오를 열어서 다시 공제양식처리 하듯이 객체들을 재생성하고 데이타를 유심히 살펴보았다.

-- 테스트 전자문서와 API설명서 및 샘플코드를 다운로드 하면 되는데 테스트 전자문서에 xml 샘플이 있다. ( 이것으로 진행하였음.)

 

 

 

 

# 다음 API Key 생성
 ref : http://www.cgimall.co.kr/happy_manual/faq_viewer_detail.cgi?db=board_faq&thread=259&page=1&search_type=&search_word=
 ref : https://www.youtube.com/watch?v=StZmev2vJS4
  ** 주의 : 키 생성시 레퍼런스 정보에 www. 를 넣으면 안됨.

 


# 로컬 API : 주소 > 좌표
 ref : http://developers.daum.net/services/apis/local/geo/addr2coord
 ex)
 https://apis.daum.net/local/geo/addr2coord?apikey={개발자 API 발급키}&q=제주 특별자치도 제주시 첨단로 242&output=json
 encodingURL = "%EC%A0%9C%EC%A3%BC%20%ED%8A%B9%EB%B3%84%EC%9E%90%EC%B9%98%EB%8F%84%20%EC%A0%9C%EC%A3%BC%EC%8B%9C%20%EC%B2%A8%EB%8B%A8%EB%A1%9C%20242"
 https://apis.daum.net/local/geo/addr2coord?apikey={개발자 API 발급키}&q=%EC%A0%9C%EC%A3%BC%20%ED%8A%B9%EB%B3%84%EC%9E%90%EC%B9%98%EB%8F%84%20%EC%A0%9C%EC%A3%BC%EC%8B%9C%20%EC%B2%A8%EB%8B%A8%EB%A1%9C%20242&output=json
 

 

요청사항은 직방 처럼 구현해달라는 것.

프로젝트 진행할 때 WPF내 웹브라우저 컨트롤에 올렸다. ( 첨부파일 - 첨부파일로 두가지에 대한 샘플 추가 해두었음 )


# 웹브라우저 컨트롤 Scrip Callback 처리
http://stackoverflow.com/questions/16691349/invoke-a-script-in-webbrowser-and-wait-for-it-to-finish-running-synchronized

 

다음 API는 정리가 엄청 잘되어 있다.

http://apis.map.daum.net/web/

 

## 추가

 음... 네이버 기능을 추가하는 것 때문에 네이버 지도를 연결중이다.

 - 네이버 지도는 api key를 받을때의 url 경로를 맞춰주어야 이게 열린다.

  발급시 http://도메인/Map/   요렇게 발급했으면

  웹서버에서 도메인의 Map폴더 아래 구현된 맵html 파일을 웹에서 호출해야 뜬다. ㅡ.,ㅡ;; ( 다음은 일단 로컬에서 페이지 개발이 가능한데...)

 

  다음 지도역시 웹서버에 올리면 웹url이 안맞으면 동작이 안됨. 단, 네이버와 다르게 하위 디렉토리까지는 체크 안하는 듯 하다.