5/17/2013

Point-In-Polygon Algorithm


very simple and smart Algorithm.

http://alienryderflex.com/polygon/

Figure 1

Figure 1 demonstrates a typical case of a severely concave polygon with 14 sides.  The red dot is a point which needs to be tested, to determine if it lies inside the polygon.

The solution is to compare each side of the polygon to the Y (vertical) coordinate of the test point, and compile a list of nodes, where each node is a point where one side crosses the Y threshold of the test point. In this example, eight sides of the polygon cross the Y threshold, while the other six sides do not.  Then, if there are an odd number of nodes on each side of the test point, then it is inside the polygon; if there are an even number of nodes on each side of the test point, then it is outside the polygon.  In our example, there are five nodes to the left of the test point, and three nodes to the right.  Since five and three are odd numbers, our test point is inside the polygon.

(Note:  This algorithm does not care whether the polygon is traced in clockwise or counterclockwise fashion.)


Figure 2

Figure 2 shows what happens if the polygon crosses itself.  In this example, a ten-sided polygon has lines which cross each other.  The effect is much like “exclusive or,” or XOR as it is known to assembly-language programmers.  The portions of the polygon which overlap cancel each other out.  So, the test point is outside the polygon, as indicated by the even number of nodes (two and two) on either side of it.


Figure 3

In Figure 3, the six-sided polygon does not overlap itself, but it does have lines that cross.  This is not a problem; the algorithm still works fine.


Figure 4

Figure 4 demonstrates the problem that results when a vertex of the polygon falls directly on the Y threshold.  Since sides a and b both touch the threshold, should they both generate a node?  No, because then there would be two nodes on each side of the test point and so the test would say it was outside of the polygon, when it clearly is not!

The solution to this situation is simple.  Points which are exactly on the Y threshold must be considered to belong to one side of the threshold.  Let’s say we arbitrarily decide that points on the Y threshold will belong to the “above” side of the threshold.  Then, side a generates a node, since it has one endpoint below the threshold and its other endpoint on-or-above the threshold.  Side b does not generate a node, because both of its endpoints are on-or-above the threshold, so it is not considered to be a threshold-crossing side.


Figure 5

Figure 5 shows the case of a polygon in which one of its sides lies entirely on the threshold.  Simply follow the rule as described concerning Figure 4.  Side c generates a node, because it has one endpoint below the threshold, and its other endpoint on-or-above the threshold.  Side d does not generate a node, because it has both endpoints on-or-above the threshold.  And side e also does not generate a node, because it has both endpoints on-or-above the threshold.


Figure 6

Figure 6 illustrates a special case brought to my attention by John David Munch of Cal Poly.  One interior angle of the polygon just touches the Y-threshold of the test point.  This is OK.  In the upper picture, only one side (hilited in red) generates a node to the left of the test point, and in the bottom example, three sides do.  Either way, the number is odd, and the test point will be deemed inside the polygon.


Polygon Edge

If the test point is on the border of the polygon, this algorithm will deliver unpredictable results; i.e. the result may be “inside” or “outside” depending on arbitrary factors such as how the polygon is oriented with respect to the coordinate system.  (That is not generally a problem, since the edge of the polygon is infinitely thin anyway, and points that fall right on the edge can go either way without hurting the look of the polygon.)


C Code Sample

//  Globals which should be set before calling this function:
//
//  int    polySides  =  how many corners the polygon has
//  float  polyX[]    =  horizontal coordinates of corners
//  float  polyY[]    =  vertical coordinates of corners
//  float  x, y       =  point to be tested
//
//  (Globals are used in this example for purposes of speed.  Change as
//  desired.)
//
//  The function will return YES if the point x,y is inside the polygon, or
//  NO if it is not.  If the point is exactly on the edge of the polygon,
//  then the function may return YES or NO.
//
//  Note that division by zero is avoided because the division is protected
//  by the "if" clause which surrounds it.


bool pointInPolygon() {

  int   i, j=polySides-1 ;
  bool  oddNodes=NO      ;

  for (i=0; i     if (polyY[i]=y
    ||  polyY[j]=y) {
      if (polyX[i]+(y-polyY[i])/(polyY[j]-polyY[i])*(polyX[j]-polyX[i])         oddNodes=!oddNodes; }}
    j=i; }

  return oddNodes; }


Here’s an efficiency improvement provided by Nathan Mercer.  The blue code eliminates calculations on sides that are entirely to the right of the test point.  Though this might be occasionally slower for some polygons, it is probably faster for most.

//  Globals which should be set before calling this function:
//
//  int    polySides  =  how many corners the polygon has
//  float  polyX[]    =  horizontal coordinates of corners
//  float  polyY[]    =  vertical coordinates of corners
//  float  x, y       =  point to be tested
//
//  (Globals are used in this example for purposes of speed.  Change as
//  desired.)
//
//  The function will return YES if the point x,y is inside the polygon, or
//  NO if it is not.  If the point is exactly on the edge of the polygon,
//  then the function may return YES or NO.
//
//  Note that division by zero is avoided because the division is protected
//  by the "if" clause which surrounds it.


bool pointInPolygon() {

  int   i, j=polySides-1 ;
  bool  oddNodes=NO      ;

  for (i=0; i     if ((polyY[i]< y && polyY[j]>=y
    ||   polyY[j]< y && polyY[i]>=y)
    &&  (polyX[i]<=x || polyX[j]<=x)) {
      if (polyX[i]+(y-polyY[i])/(polyY[j]-polyY[i])*(polyX[j]-polyX[i])         oddNodes=!oddNodes; }}
    j=i; }

  return oddNodes; }


Here’s another efficiency improvement provided by Lascha Lagidse.  The inner “if” statement is eliminated and replaced with an exclusive-OR operation.

//  Globals which should be set before calling this function:
//
//  int    polySides  =  how many corners the polygon has
//  float  polyX[]    =  horizontal coordinates of corners
//  float  polyY[]    =  vertical coordinates of corners
//  float  x, y       =  point to be tested
//
//  (Globals are used in this example for purposes of speed.  Change as
//  desired.)
//
//  The function will return YES if the point x,y is inside the polygon, or
//  NO if it is not.  If the point is exactly on the edge of the polygon,
//  then the function may return YES or NO.
//
//  Note that division by zero is avoided because the division is protected
//  by the "if" clause which surrounds it.


bool pointInPolygon() {

  int   i, j=polySides-1 ;
  bool  oddNodes=NO      ;

  for (i=0; i     if ((polyY[i]< y && polyY[j]>=y
    ||   polyY[j]< y && polyY[i]>=y)
    &&  (polyX[i]<=x || polyX[j]<=x)) {
      oddNodes^=(polyX[i]+(y-polyY[i])/(polyY[j]-polyY[i])*(polyX[j]-polyX[i])     j=i; }

  return oddNodes; }


Integer Issue

What if you’re trying to make a polygon like the blue one below (Figure 7), but it comes out all horizontal and vertical lines, like the red one?  That indicates that you have defined some of your variables as integers instead of floating-point.  Check your code carefully to ensure that your test point and all the corners of your polygon are defined as, and passed as, floating-point numbers.

   Figure 7

5/16/2013

orientation event fix - android


Reacting to Configuration Changes

Start be adding the android:configChanges node to your Activity's manifest node

android:configChanges="keyboardHidden|orientation"

setContentView to force the GUI layout to be re-done in the new orientation.


@Override
public void onConfigurationChanged(Configuration newConfig) {
  super.onConfigurationChanged(newConfig);
  setContentView(R.layout.myLayout);
}

5/01/2013

ELO / MTouch Serial Interface direct control.



Development sequence.

1. Serial Port Open ( linux / win32 )

serial port setting.

elo -- rx/tx

mtouch - rx/tx  -- and cts/rts 


2. Detect ELO or MTouch

reference serial protocol from the "xinput-calibrate"  "DirectFB"  "touchcal"

3. calibrate minX,maxX,minY,maxY

calibrate UI  X11 Window / Win32 Window

4. use touch.

current status - developing.

linux - almsot finished.
win32 - win32 ui development.

1/15/2011

GUI Toolkit based on SDL -

1)aedGUI - 설치시 SDL ttf,rtf가 요구됨.(freetype 요구.)크로스 플랫폼, 사용하기 편리, SDL지원 C++ GUI Library.

2)Agar - (설치 용량 3,788,230 Bytes)2D/3D 게임과 시뮬레이션을 위한 C 응용 프레임워크. SDL 2D와 OpenGL 렌더링을 지원.에뮬레이터, 게임, 공학, 과학 시뮬레이션과 시각화 도구등에 사용 된다. Free Software이고BSD License에 의해 자유롭게 사용이 가능하다.멀티스레드 지원.(Thread 옵션으로 컴파일시,)3)Para GUI - (설치 용량 11,712,802 Bytes)SDL기반의 GUI library. SDL이 있는 환경이면 어디서나 사용 가능.다양한 플랫폼으로 컴파일이 가능하다.SDL에 완전 기반. 크로스 플랫폼 멀티미디어 응용 프로그램과 프레임 버퍼 디스플레이에서 동작하는 임베디드 디바이스의 구동을 목적으로 제작.Highlights of the library * published under LGPL * straight forward C++ class-design * cross-platform * supports alpha-blending of overlapping widgets * threadsafe * highly customizable widgets (background gradients, background images, transparency, colors, fonts) * XML configuration * many standard widgets already implemented (buttons, labels, scrollbars, progressbars, windows ...) * create your own widgets (subclass an existing widget) * supports various imagetypes through SDL_Image (configurable at compile time) * using libSigC++ as callback framework

3/31/2010

function gurad and unguard

COPY from naver.com

flipcode - UT2K3 Exception Handling 를 보면 알겠지만, Unreal Engine에서는 guard / unguard라는 매크로를 이용해서 프로그램이 비정상적인 동작을 하여 종료하기 직전에 콜스택을 화면에 보여주고 우아하게 죽는다.

guard / unguard 매크로라는 것은 설정에 따라 다르게 정의되지만, 기본적으로는 다음과 같은 간단한 매크로인데...

#define guard(func) {static const TCHAR __FUNC_NAME__[]=TEXT(#func); try{
#define unguard }catch(TCHAR*Err){throw Err;}catch(...){appUnwindf(TEXT("%s"),__FUNC_NAME__); throw;}}

요지는 함수 이름을 저장해놨다가 exception이 발생하면 현재 함수 이름을 appUnwindf를 통해서 뿌리던가 하고 exception을 다시 던져서 상위 레벨의 catch가 또 처리하게 하는 것이다. (appUnwindf 구현은 알아서)

try / catch라는 것은 exception이 발생했을 때 무거운 것이지, 그냥 try에 들어가서 문제없이 빠져나올 때는 큰 문제가 안되기 때문에, 함수마다 사용해도 큰 문제는 없다. 문제가 되면 flipcode - Function Guarding처럼 guard의 레벨을 나눠서 사용해도 된다.

그러면 함수에서는

UBOOL Encode( FArchive& In, FArchive& Out )
{
guard(FCodecBWT::Encode);



return 0;

unguard;
}

이런 식으로 guard를 해주고 싶은 함수마다 guard / unguard 를 쓰고, guard 안에 함수 이름(또는 원하는 텍스트)을 채워야 하는데, 처음부터 이렇게 짰다면 모를까, 프로젝트 후반부에 이걸 적용하자! 라고 했다가는 감당이 안되는 것이다.

2005년 8월 17일, 조프의 E모 프로젝트의 서버에서 저 비슷한 것을 도입해야 한다는 결정이 나와서, 천장을 멍하니 보다가, guard/unguard의 구현은 ㅤㄱㅜㅊ은일 다해주는 석중에게 넘기긴 하였으나, 이제와서 저 입력을 매 함수마다 시키자니 사람이 시킬 짓이 아닌지라... 고민하던 와중에 석중이 기억해냈다.

__FUNCTION__

VC++에는 __FUNCTION__, 등등의 매크로가 있어서 __FILE__과 마찬가지로 __FUNCTION__이 함수 안에서 쓰일 때 함수 이름에 해당하는 문자열로 치환되는 것이다.1 비슷한 매크로가 두 개 쯤 더 있지만, 함수 이름이 얼마나 지독하게 나오냐 차이니 넘어가고...

좌우지간, 할 일은 두가지인데,

1. 매번 함수 이름을 채울 필요가 없게 하자

//#define guardfunc guard(__FUNCTION__) // 이건 안 될 수도
#define guardfunc {static const TCHAR __FUNC_NAME__[]=TEXT(__FUNCTION__); try{

끝.

UBOOL Encode( FArchive& In, FArchive& Out )
{
guardfunc;



return 0;

unguard;
}

이제는 이렇게만 해주면 알아서 함수 이름이 들어간다.

직접 문자열을 쓰고 싶을 때는 guard를 사용하면 된다.

2. 원하는 함수에 guardfunc / unguard를 쉽게 추가할 수 있도록 하자

비주얼 스튜디오는 나름 매크로라는 것을 지원한다.


현재 캐럿 위치에서 위쪽으로 앞에 빈 칸이 없는 '{'를 찾는다.
그 뒤에 '새 줄 + 탭 + guardfunc; + 새 줄'을 추가한다
그 위치에서 아래쪽으로 앞에 빈 칸이 없는 '}'를 찾는다.
그 앞에 '새 줄 + 탭 + unguard; + 새 줄'을 추가한다.
는 간단한 매크로를 짜는 것으로 해결했다. 함수의 시작과 끝을 제대로 인식해서 처리하면 좋겠다는 생각을 해봤으나 너무 귀찮았다.

비주얼 스튜디오는 나름 자동 인덴트를 해주고, 성격이 괴팍한 프로그래머가 아닌 다음에야 함수의 몸통을 둘러싸는 괄호 앞에 탭이나 공백을 주지는 않을터이니 이 정도면 그럭저럭 합리적인 해결책이라고 생각한다.

이 매크로를 단축키에 등록하고, 함수 안에서 단축키를 눌러주면 알아서 guardfunc;와 unguard;가 추가된다. (사실은 함수 밖에서 누르면 그 위에 있는 함수를 찾아서 그 함수에 추가한다)

guardfunc가 이미 있으면 새로 추가를 안하게 한다거나, 토글이 되게 한다거나 하면 아주 우아할 것 같지만, 없어도 크게 아쉽지 않은 기능이므로 생략.

매크로 코드는 다음과 같다.

Option Strict Off
Option Explicit Off

Imports EnvDTE
Imports System.Diagnostics

Public Module 뭔가이름을

Sub AddFunctionGuard()
'Description: Creates a guard block for the currently selected C/C++ function
Dim selection As TextSelection
Dim line As Integer

If (ActiveDocument() Is Nothing) Then
Exit Sub
End If
If ActiveDocument().Language = EnvDTE.Constants.dsCPP Then

selection = DTE.ActiveDocument.Selection()
line = selection.TextRanges.Item(1).StartPoint.Line
selection.GotoLine(line, True)

If selection.FindText(vbCrLf & "{", vsFindOptions.vsFindOptionsBackwards) Then
selection.EndOfLine()
selection.Insert(vbCrLf & vbTab & "GUARDFUNC;" & vbCrLf)

selection.Cancel()
If selection.FindText(vbCrLf & "}") Then
selection.StartOfLine()
selection.Text = vbCrLf & vbTab & "UNGUARD;" & vbCrLf
End If

' GUARDFUNC가 들어갔을테니 2줄 더해준다
selection.GotoLine(line + 2)
End If

End If
End Sub


End Module



--------------------------------------------------------------------------------

없진 않은데. 클래스내 멤버펑션 선언에서 바디까지 써버린다던가... ─ㄷㅋ 2005-8-18 15:24
인라인 처리할 정도라면 guard/unguard를 안쓰거나. 직접 쓰거나. 아쉬우면 매크로를 고쳐주삼. ─조프 2005-8-18 15:31
우린 노가다로 이미 다 다 넣어서 ─ㄷㅋ 2005-8-18 15:55
답글달기
이름 기본으로 한 단락 들여쓰기입니다. 콜론(:)을 붙이면 더 들여쓸 수 있습니다.

Homepage :


regexp를 한 번 거하게 써서 코드를 뒤엎어봄이? 반쯤은 파서가 되어야 하겠지만... 누가 하루쯤 달라붙으면 충분하리라 생각하는데. ─라슈펠 2005-8-18 17:52
위에는 try...catch가 가볍다고 썼지만, 그렇다고 공짜로 돌아가는게 아니기 때문에 모든 함수에 적용시키는 것도 문제가 있어서.
그리고 우리 서버는 try...catch가 아니라 다른 식으로 구현해서 쓸 것이기 때문에. 어쨌든. 원하는 함수에 추가하는 기능으로 충부함. ─조프 2005-8-18 18:04
regexp 로 하면, ^\{ 를 {\n\tguardfunc 로 바꿔주고 ^\} 를 \tungurad\n} 로 바꿔주면 되겠군요... ─쌀밥 2005-9-8 17:51
첫번째 단락과 같은 이유로 헤더 파일에는 적용을 못하고, cpp 파일에서도 네임스페이스의 {} 쌍, enum의 {} 쌍 등등에까지 끼어들 수 있습니다. 그래서 자동은 포기. ─조프 2005-9-8 18:35
\)\s*\n\{ 를 )\n{\n\tguardfunc 으로 ^\}\n 을 \tunguard\n}\n 으로 바꾸는게 더 좋은거 같네요... ─쌀밥 2005-9-8 18:55
해보니 왠만한건 다 통과 되는데
void myFunc () {
}
이런건 안되네요;;;; vc++ 말고 vi 에서 하면 ^([^\{]+\)\s*\n\{\n) 를 \1\nguardfunc\n 으로 될거 같은데... vc++ 에서는 참조(\1, \2 등등..)가 안되는듯;; ─쌀밥 2005-9-8 19:05
답글달기
이름 기본으로 한 단락 들여쓰기입니다. 콜론(:)을 붙이면 더 들여쓸 수 있습니다.

Homepage :


그리고 guardfunc; <...> unguard; 형태보다는 guardfunc { <...> } unguard;형태를 좋아하지만... 어차피 내 취향과는 별 관계 없는 일이겠지? ; ─라슈펠 2005-8-18 17:55
guard / unguard 매크로의 구현을 보면
void functionname()
guardfunc
{
}
unguard;
이라고 해도 문제 없을 것 같은데? guard와 unagurd가 {}를 포함하고 있으니까. 그렇게 쓰고 싶으면 비베 스크립트를 조금 고쳐서 쓰면 되겠지. ─조프 2005-8-18 18:06
아니 구현 문제가 아니라 코딩 스타일 문제... ; {}가 있어줘야 어디부터 어디까지가 guard영역인지 보이지 않겠나. ─라슈펠 2005-8-18 18:08
익숙해지면 괜찮아. 그리고 중첩해서 쓰기도 하지만 대부분의 경우는 함수를 통째로 감싸는 용도로 쓰기 땜시; ─조프 2005-8-18 18:51
답글달기