기본 콘텐츠로 건너뛰기

4월, 2024의 게시물 표시

이미지 크기 조절

이미지의 네 점 중 한 점($P_3$)을 이동시켜 크기를 조정하려고 합니다. 여기서 한 가지 조건이 있는데 기존의 X-Y 비율을 지켜야 한다는 것입니다. 비율은 아래와 같이 정의할 수 있습니다. $$ ratio = \frac{|\overrightarrow{P_4 - P_3}|}{|\overrightarrow{P_2 - P_1}|} $$ $P_2$의 $x$ 값을 $P$의 $x$으로 바꾸고 $length = \overrightarrow{|P_2 - P_1|}$의 길이를 구합니다. $P_4$의 $y$값은 앞서 구한 $length$에 $ratio$를 곱하여 구할 수 있습니다. $${P_4}_.y = {P_1}_.y + length * ratio$$ 위에서는 아주 특수한 경우에 대해서 생각을 했었고 우리는 일반적인 경우(회전된 경우 포함)에 대해서 처리해야만 합니다. 우선 ${P_2}^\prime$는 아래와 같이 구할 수 있습니다. $$ \begin{align} AxisX &= \frac{\overrightarrow{P_2 - P_1}}{\overrightarrow{|P_2 - P_1|}}\\ dot &= AxisX \cdot \overrightarrow{P - P_1}\\ {P_2}^\prime &= P_1 + AxisX * dot\\ \end{align} $$ 그리고 ${P_4}^\prime$는 아래와 같이 구할 수 있습니다. $$ \begin{align} AxisY &= \frac{\overrightarrow{P_4 - P_1}}{\overrightarrow{|P_4 - P_1|}}\\ {P_4}^\prime &= P_1 + AxisY * dot*ratio\\ \end{align} $$ 최종적으로 ${P_3}^\prime$는 아래와 같습니다. $$ {P_3}^\prime = P_1 + AxisX *dot + AxisY * dot * ratio $$ 이로써 기존의 비율을 유지한 채 직사각형의 크기를 바꿀

[윈도우즈 서비스] 설치 파일 만들기(WIX) - #4

이제 윈도우즈 서비스를 다 만들었기 때문에 설치 파일을 만들어 보겠습니다. 저희 같은 경우에는 불특정 다수의 PC에 설치하는 것이 아니고 서버에만 설치하면 되기 때문에 파일을 서버에 복사한 뒤 [윈도우즈 서비스] Console 실행 - #1 에서 설명한 방식대로 서비스를 등록해도 됩니다. 하지만 설치 파일을 만들면 이러한 작업을 자동으로 해주기 때문에 번거로운 작업을 하지 않아도 됩니다. WIX를 이용하여 윈도우즈 서비스를 등록하는 방법을 알아보도록 하겠습니다. How To: Install a Windows service To install a Windows service, use the  ServiceInstall  element. Other configuration can be made using the  ServiceControl  element and the  ServiceConfig  element from WixUtilExtension. Step 1: Install the service The  ServiceInstall  element contains the basic information about the service to install. This element should be the child of a  Component  element whose key path is a sibling  File  element that specifies the service executable file. Tip:  to specify a system account, such as LocalService or NetworkService, use the prefix  NT AUTHORITY . For example, use  NT AUTHORITY\LocalService  as the  Account  attribute value to run the service under this account. ServivceInstall

[윈도우즈 서비스] log4net - #3

이제 윈도우즈 서비스에서 프로세스를 이용하여 작업을 수행 할 수 있습니다. 이전 글에서도 이야기 한 것처럼 로그를 남기는 것은 중요한 부분입니다. log4net - Adding appenders programmatically log4net을 이용한 logging Dynamic log fileNames with log4net 로그를 남겨야만 프로그램이 오작동 했을 때 원인을 유추해 볼 수 있습니다. 그래서 윈도우즈 서비스와 프로세스 둘 다 로그를 남기기로 하고 설정을 했습니다. Cofiguration 예제 <?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" /> </configSections> <log4net> <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender"> <file type="log4net.Util.PatternString" value="${programdata}\FinalService\Process\Log\"/> <appendtofile value="true"/> <datepattern value="yyyy-MM-dd'.log'"/> <staticlogfilename value="false"/>

[윈도우즈 서비스] Console 실행 - #2

윈도우즈 서비스에서 타이머를 돌려 문서 목록을 가져와 Console 프로그램(프로세스)을 실행시켜 작업을 처리하려고 합니다. 1. 프로세스를 계속 생성할 수 없으므로 지정한 갯수만큼만 생성하고, 2. 프로세스가 작업을 완료하면 문서 목록에서 문서를 삭제합니다. 이를 바탕으로 그려본 흐름도입니다. DB에서 FinalPDF를 생성할 문서 정보를 가져옴 프로세스 수가 지정된 갯수보다 작다 FinalPDF를 생성할 문서가 있을 때까지 실행중인 프로세스를 구함 프로세스 시작 END N Y 위 흐름도에서 예외 사항을 고려해보면, 오래 걸리는 작업일 경우 작업 처리 중에 타이머 시간이 돌아오면 동일한 작업을 수행하는 프로세스를 다시 실행하게 됩니다. 이런 경우를 대비하기 위해 프로세스를 실행할 때 작업 문서에 프로세스 ID를 저장합니다. 이렇게 하면 중복 작업을 막을 수 있습니다. 타이머 시간이 되면 프로세스 ID를 가진 문서는 실제 프로세스가 돌아가는지 확인하여 프로세스가 돌아가지 않는다면, 작업이 완료된 경우 : 문서 목록에서 해당 문서를 제거합니다. 작업이 완료되지 못한 경우 : 프로세스를 다시 실행시킵니다. 아래는 개선한 흐름도와 의사(PSEUDO) 코드입니다. DB에서 FinalPDF를 생성할 문서 정보를 가져옴 프로세스 수가 지정된 갯수보다 작다 FinalPDF를 생성할 문서가 있을 때까지 실행중인 프로세스를 구함 해당 문서의 프로세스가 실행 중? 프로세스 시작 END N Y N var process = Process.Start(startInfo); /// process.Id를 저장 ... private void _Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { var clone = DocumentProcessMap.ToDictionary(x => x

Diff 알고리즘 활용

실제 프로젝트에서 Diff 알고리즘을 활용한 예를 보도록 하겠습니다. 아래와 같은 목록을 가지고 3D로 알아서? 모델링하는 경우를 생각해 봅시다. CONCENTRIC, FLEXIBLE HOSE, CHECK, BUTTERFLY, GATE, FLANGE 사용자가 요구 사항 으로 목록의 항목을 더블 클릭했을때 해당하는 모델을 하이라이트하는 기능을 만들고자 합니다. 항목은 아래와 같은 Class로 정의됩니다. class Item { public string UID{get;set;} public string Type{get;set;} } 쉽게 생각해보면 모델을 생성할 때 해당 Item의 UID를 속성을 넣어 준다면, 위 기능을 구현할 수 있습니다. 하지만 외부에서 만들어진 모델(Type은 알고 있지만 UID 값을 가지지 않음)을 가지고 위 기능을 만들려면 어떻게 해야 할까요? 먼저 모델의 UID를 대응하는 Item의 UID로 업데이트하여 동기화 시켜야 합니다. 순차적으로 나타나는 Type으로 유추하면 되지 않을까 생각할지도 모르겠지만 동일한 Type이 여러개 나올 수 있다고 생각하면 올바른 방법이 아닌것 같습니다. 이때 Diff 알고리즘을 활용할 수 있을것 같습니다. 여기 서 코드를 다운받을 수 있습니다. Type을 NewLine으로 연결하여 lhstr, rhstr를 생성합니다. 그리고 나서 DiffText 함수를 호출하면 var diffs = Diff.DiffText(lhstr, rhstr, true, true, true).Reverse(); 나중에 추가, 삭제된 부분을 제거하기 위해 결과 값을 역 정렬했습니다. lhs에서는 추가된 정보를, rhs에서는 삭제된 정보를 리턴하고 있습니다. 위 예에서 lhs에서는 2개 항목이 삭제되었고, rhs에서는 4개 항목이 추가되었다고 합니다. 변경된 항목을 제거하면 즉 lhs에서 2개 항목을 삭제하고, rhs에서 4개 항목을 삭제하면, lhs, rhs의 항목의 수는