Showing posts with label OSG. Show all posts
Showing posts with label OSG. Show all posts

Tuesday, September 9, 2008

Algorithm to buffer a polygon

I came across the need to buffer a polygon. Of course, ESRI provides tool in ArcMap to achieve this, but I needed an algorithm to use in an application rather than a tool. I could not find the algorithm, but I found the code to achieve this. Still, it should be fairly easy to figure out the algorithm by reading the code. You can find by clicking here. It's in VB, so I had to convert it to C++.

In case the link is broken, I am including the source code:

Private Type XY
p_X As Double
p_Y As Double
End Type
Dim MyPoly() As XY
Dim MyPoly2() As XY
Dim MyMidLines() As XY
Dim MyLine() As XY

Private Sub OUTLINE_IT()
'MyPoly is a matrix from 0 to N, containing the X and Y values of the
'points of the original polygon
'MyPoly2 is the Output Poly

Dim I As Integer
Dim PI As Integer
Dim NI As Integer '
Dim p_1 As XY
Dim p_2 As XY
Dim t1 As Double
Dim t2 As Double
Dim MidP As XY
Dim MySign As Integer

ReDim MyMidLines(UBound(MyPoly))
ReDim MyPoly2(UBound(MyPoly))
ReDim MyLine(UBound(MyPoly))
Dim MyD As Long
MyD = Val(txtSize.Text)
MySign = Sgn(MyD)
Picture1.Cls
If MySign <> 0 Then
For I = 0 To UBound(MyPoly)
PI = ((I - 1) + UBound(MyPoly) + 1) Mod (UBound(MyPoly) + 1)
NI = ((I + 1) + UBound(MyPoly) + 1) Mod (UBound(MyPoly) + 1)
Picture1.Line (MyPoly(I).p_X, MyPoly(I).p_Y)-(MyPoly(NI).p_X, MyPoly(NI).p_Y), vbBlack
MyLine(I).p_X = MyPoly(NI).p_X - MyPoly(I).p_X
MyLine(I).p_Y = MyPoly(NI).p_Y - MyPoly(I).p_Y
t1 = Sqr(((MyPoly(PI).p_X - MyPoly(I).p_X) ^ 2 + (MyPoly(PI).p_Y - MyPoly(I).p_Y) ^ 2) / _
((MyPoly(NI).p_X - MyPoly(I).p_X) ^ 2 + (MyPoly(NI).p_Y - MyPoly(I).p_Y) ^ 2))
MidP.p_X = (MyPoly(PI).p_X + (MyPoly(NI).p_X - MyPoly(I).p_X) * t1 + MyPoly(I).p_X) / 2
MidP.p_Y = (MyPoly(PI).p_Y + (MyPoly(NI).p_Y - MyPoly(I).p_Y) * t1 + MyPoly(I).p_Y) / 2

MyMidLines(I).p_X = (MidP.p_X - MyPoly(I).p_X)
MyMidLines(I).p_Y = (MidP.p_Y - MyPoly(I).p_Y)

Next I

t1 = MySign * Sqr((MyD ^ 2) / (MyMidLines(0).p_X ^ 2 + MyMidLines(0).p_Y ^ 2))

MyPoly2(0).p_X = t1 * MyMidLines(0).p_X + MyPoly(0).p_X
MyPoly2(0).p_Y = t1 * MyMidLines(0).p_Y + MyPoly(0).p_Y

For I = 0 To UBound(MyPoly)
PI = ((I - 1) + UBound(MyPoly) + 1) Mod (UBound(MyPoly) + 1)
NI = ((I + 1) + UBound(MyPoly) + 1) Mod (UBound(MyPoly) + 1)
t2 = (MyLine(I).p_Y * MyPoly2(I).p_X - MyLine(I).p_X * MyPoly2(I).p_Y + MyLine(I).p_X * MyPoly(NI).p_Y - _
MyLine(I).p_Y * MyPoly(NI).p_X) / (MyLine(I).p_Y * MyMidLines(NI).p_X - MyLine(I).p_X * MyMidLines(NI).p_Y)
MyPoly2(NI).p_X = MyMidLines(NI).p_X * t2 + MyPoly(NI).p_X
MyPoly2(NI).p_Y = MyMidLines(NI).p_Y * t2 + MyPoly(NI).p_Y
Picture1.Line (MyPoly2(I).p_X, MyPoly2(I).p_Y)-(MyPoly2(NI).p_X, MyPoly2(NI).p_Y), vbBlack
Next I
End If

End Sub

Wednesday, August 27, 2008

Error showing "Run-Time Check Failure #0"

After compiling the source code of OSG 2.6.0 and MANUALLY copying the binaries to another directory, I got the error message:

Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.

This error pops up when I run an OSG application in VS2005 in Debug mode. This error looks a little scary, but after looking for information about this error, I found http://www.gamedev.net/community/forums/topic.asp?topic_id=308819 which pointed me in the right direction. It was because I copied the dll's and include directory (*dll, *.h), but not the library files (*.lib) to a new directory. I guess that is why there is an INSTALL project in the OSG solution that copies the files automatically :)

Saturday, February 2, 2008

OSG scene viewed inside a .NET control

This is an interesting challenge. This is what I did: I created two threads, one for the main form and one for the OSG loop. This second thread shall run a method that receives a handle as a parameter. This handle can be either a handle to the form or a handle to a control (i.e. Panel) and is assigned as follows:

new osgViewer::GraphicsWindowWin32::WindowData(hwnd);

The method that is run by the second thread contains the usual instructions to render a scene in OSG. Of course, this is done in C++ and called from C#.

I run into a problem while doing this: it is not possible to access a control "from other than the thread it was created on" (Cross-thread operation error). After doing some investigation I found this can be fixed using:

CheckForIllegalCrossThreadCalls = false;

Still, this is a quick fix and I do not think is the solution for a commercial app. Visual Studio 2005 has more checking than Visual Studio 2003, therefore if you are running 2003 you might not receive this error.