Moore Neighborhood tracing help needed
Monkey Forums/Monkey Programming/Moore Neighborhood tracing help needed
| ||
I have made an PNG outline tracer a week ago, but that was not good enough for what I want to do with it. Now I'm trying for more then a week to get the coordinates clockwise and I know how. But I can't create the correct monkey code for it :( Its this solution http://en.wikipedia.org/wiki/Moore_neighborhood http://www.imageprocessingplace.com/downloads_V3/root_downloads/tutorials/contour_tracing_Abeer_George_Ghuneim/moore.html What I have - does check if the next pixel is not alpha 0 What I don't have - loop needs to stop when its find the first pixel again - find the whole outline Thanks very much :) Strict Import mojo Import opengl.gles11 Function Main:Int() New MyApp() Return 0 End Class MyApp Extends App Field thing:Sprite Method OnCreate:Int() SetUpdateRate(60) thing = New Sprite() Return 0 End Method OnUpdate:Int() thing.Update() Return 0 End Method OnRender:Int() Cls(255,255,255) thing.Draw() Return 0 End End Class PNGTracer Field startX:Int = 93 Field startY:Int = 0 Field size:Int[2] Field _w:Int Field _h:Int Field db:DataBuffer Field xy:Stack<Point> = New Stack<Point>() Field data:Int[] Function Get:Int[] (_db:DataBuffer,_w:Int,_h:Int) Local data:Int[_w * _h] For Local y:Int = 0 Until _h For Local x:Int = 0 Until _w Local j:Int = _db.PeekInt( ( y * _w + x) * 4) data[y * _w + x] = (j & $ff000000) | ( (j & $00ff0000) Shr 16) | (j & $0000ff00) | ( (j & $000000ff) Shl 16) Next Next Return data End Function Method neighbor:Void(_x:Int,_y:Int) '' Print _data.Length() Print "Start:"+_x+","+_y Local check:Bool[8] Local calc:Point[8] check[0] = (_y-1)*_w+(_x-1)>=0 And (data[(_y-1)*_w+(_x-1)] shr 24) & $FF calc[0] = New Point(_x-1,_y-1) check[1] = (_y-1)*_w+_x>=0 And (data[(_y-1)*_w+_x] shr 24) & $FF calc[1] = New Point(_x,_y-1) check[2] = (_y-1)*_w+(_x+1)>=0 And (data[(_y-1)*_w+(_x+1)] shr 24) & $FF calc[2] = New Point(_x+1,_y-1) check[3] = _y*_w+(_x+1)>=0 And (data[_y*_w+(_x+1)] shr 24) & $FF calc[3] = New Point(_x+1,_y) check[4] = (_y+1)*_w+(_x+1)>=0 And (data[(_y+1)*_w+(_x+1)] shr 24) & $FF calc[4] = New Point(_x+1,_y+1) check[5] = (_y+1)*_w+_x>=0 And (data[(_y+1)*_w+_x] shr 24) & $FF calc[5] = New Point(_x,_y+1) check[6] = (_y+1)*_w+(_x-1)>=0 And (data[(_y+1)*_w+(_x-1)] shr 24) & $FF calc[6] = New Point(_x-1,_y+1) check[7] = _y*_w+(_x-1)>=0 And (data[_y*_w+(_x-1)] shr 24) & $FF calc[7] = New Point(_x-1,_y) Local index:Int = 0 For Local hit:Bool = Eachin check If hit Then ' FOUND THE NEXT GOOD PIXEL ! Print "hit:"+index Print "add:"+calc[index].x+","+calc[index].y xy.Push(New Point(calc[index].x,calc[index].y)) '' neighbor(calc[index].x,calc[index].y) ' uncomment and there is a crash Exit End index+=1 Next End Method Trace:Stack<Point>(_img:String) db = LoadImageData(_img, size) data = Get(db,size[0],size[1]) _w = size[0] 'helper var _h = size[1] 'helper var neighbor(startX,startY) Return xy End Function toPolyData:Float[](_data:Stack<Point>) Local verts:Float[_data.Length*2] Local tmpI:Int = 0 For Local point:Point = Eachin _data verts[tmpI] = point.x tmpI=tmpI+1 verts[tmpI] = point.y tmpI=tmpI+1 Next Return verts End End Class Point Field x:Int Field y:Int Method New(_x:Int,_y:Int) x=_x y=_y End End Class Sprite Field image:Image Field tmp:Image Field outline_xy:Stack<Point> = New Stack<Point>() Field verts:Float[] Method New() Local PNGTrace:PNGTracer = New PNGTracer() outline_xy = PNGTrace.Trace("monkey://data/test-thing2.png") '' verts = PNGTracer.toPolyData(outline_xy) End Method Draw:Void() SetColor(255,0,0) For Local point:Point = Eachin outline_xy DrawPoint(point.x,point.y) Next '' DrawPoly(verts) End Method Update:Void() '' If PointInPoly(MouseX(),MouseY(),verts) Then '' Print "Hit" '' Else '' Print "no" '' End End Function PointInPoly:Bool(x:Float, y:Float, poly:Float[]) Local i:Int, j:Int, c:Bool Local v1:Bool, v2:Bool, v3:Bool, v4:Bool, v5#, v6#, v7# c = False Local p_count% = (poly.Length() / 2) For i = 0 To p_count-1 j = (i+1) Mod p_count v1 = (poly[i*2+1] <= y) v2 = (y < poly[j*2+1]) v3 = (poly[j*2+1] <= y) v4 = (y < poly[i*2+1]) v5 = (poly[j*2]-poly[i*2]) * (y-poly[i*2+1]) v6 = (poly[j*2+1]-poly[i*2+1]) If v6 = 0.0 Then v6 = 0.0001 v7 = poly[i*2] If (((v1 And v2) Or (v3 And v4)) And (x < v5 / v6 + v7)) Then c = Not c Next Return c End End Still using this image: ![]() |