Omnimaga

Calculator Community => TI Calculators => Axe => Topic started by: kindermoumoute on November 11, 2010, 05:30:01 pm

Title: filling subroutine
Post by: kindermoumoute on November 11, 2010, 05:30:01 pm
I'm looking to make a function filling like paint. I already tried some stuff, but I think I share in the wrong direction :
Code: [Select]
:2→Z
:sub(FIL,X,Y)
:...
:Lbl FIL
:r1→{L1+Z}
:r2→{L1+Z+1}
:While Z
: !If pxl-Test({L1+Z},{L1+Z+1})
: Pxl-On({L1+Z},{L1+Z+1})
: Z+2→Z
: sub(FIL,r1,r2+1)
: Z-2→Z
: sub(FIL,r1,r2-1)
: Z-2→Z
: sub(FIL,r1+1,r2)
: Z-2→Z
: sub(FIL,r1-1,r2)
: End
: Z-2→Z
:End
:Return
Title: Re: filling subroutine
Post by: SirCmpwn on November 11, 2010, 05:32:37 pm
I don't have code, but this should help:
http://en.wikipedia.org/wiki/Flood_fill (http://en.wikipedia.org/wiki/Flood_fill)
Title: Re: filling subroutine
Post by: kindermoumoute on November 11, 2010, 05:33:46 pm
I already read this, but I can't find how to use in Axe Parser (r1 is always same variable).
Title: Re: filling subroutine
Post by: SirCmpwn on November 11, 2010, 05:36:47 pm
Make sure you have the latest version of Axe and try this:
Code: [Select]
.r1 = X, r2 = Y
Lbl FF
ReturnIf Pxl-Test(r1,r2)
Pxl-On(r1,r2)
sub(FFʳ,r1+1,r2
sub(FFʳ,r1-1,r2
sub(FFʳ,r1,r2-1
sub(FFʳ,r1,r2+1
Return

EDIT: Fixed code
EDIT2: I tested this, and it works, but make sure that you only do it with a small area or you will end up overflowing the stack, which would be bad.
Title: Re: filling subroutine
Post by: kindermoumoute on November 11, 2010, 05:59:54 pm
Wow... usefull ʳ :o
Correction with screen limit :
Code: [Select]
:Lbl FIL
:If Pxl-Test(r1,r2) or (r1≥96) or (r2≥64)
:Return
:End
:Pxl-On(r1,r2)
:sub(FILr,r1+1,r2)
:sub(FILr,r1-1,r2)
:sub(FILr,r1,r2-1)
:sub(FILr,r1,r2+1)
:Return
pretty routine, thank ;)
Title: Re: filling subroutine
Post by: SirCmpwn on November 11, 2010, 06:00:39 pm
Woah, careful there.  Filling the whole screen, or even most of it, will cause a stack overflow, which will crash the calc.
Title: Re: filling subroutine
Post by: kindermoumoute on November 11, 2010, 06:01:56 pm
It work perfectly, don't crash (with screen limit).
Title: Re: filling subroutine
Post by: SirCmpwn on November 11, 2010, 06:02:25 pm
Oh really?  Okay then, glad to hear it.
Title: Re: filling subroutine
Post by: kindermoumoute on November 11, 2010, 06:31:05 pm
OK, there is 1 random bugs and always final crash ;D
Title: Re: filling subroutine
Post by: SirCmpwn on November 11, 2010, 06:36:11 pm
That first one is weird, and it's probably a stack overflow.  The second one is probably a problem with your code.
Title: Re: filling subroutine
Post by: kindermoumoute on November 11, 2010, 06:40:41 pm
What is a stack overflow ? How prevent that ?
Title: Re: filling subroutine
Post by: SirCmpwn on November 11, 2010, 06:44:58 pm
The stack is like a stack of papers.  You can put stuff on top, and take stuff off.  The last thing on is the first thing off.  The calculator has its own internal stack.  When you use use sub(FFr, it adds r1, r2, r3, r4, r5, and r6 to the top of the stack.  The stack is a fixed size, though.  You can only put so much paper on before the calculator crashes.  There is an alternative flood-fill method that is designed to prevent this, but it's more complex, so I'll have to work on that for you later.
Title: Re: filling subroutine
Post by: Builderboy on November 11, 2010, 06:46:29 pm
Yeah, and let it be noted that its not the size necessarily that makes the stack overflow, but the complexity of the filling field.
Title: Re: filling subroutine
Post by: SirCmpwn on November 11, 2010, 06:47:50 pm
Exactly what BuilderBoy said.
Also, is L1 available for storage when working on a better routine?
Title: Re: filling subroutine
Post by: Builderboy on November 11, 2010, 06:52:13 pm
Actually, i retract what i just said XD its difficult to predict what will crash and what will not.  Smaller is generally safer though :)
Title: Re: filling subroutine
Post by: SirCmpwn on November 11, 2010, 06:52:35 pm
Well, what you just said happens to be true.
Title: Re: filling subroutine
Post by: Builderboy on November 11, 2010, 06:54:19 pm
Well for instance if you try to fill the entire screen from the top left hand corner, the algorithm will travel back and forth, down the entire screen until it gets to the bottom, at which point every single point on the screen will be in the stack.  Even though the screen is very simple, it poses the least efficient stack usage.
Title: Re: filling subroutine
Post by: SirCmpwn on November 11, 2010, 06:55:07 pm
Yeah.  There are better ways, which I will help you with later, kindermonumonte.
Title: Re: filling subroutine
Post by: kindermoumoute on November 11, 2010, 06:57:03 pm
OK, thank.
Title: Re: filling subroutine
Post by: kindermoumoute on December 08, 2010, 01:49:12 pm
Up.
Title: Re: filling subroutine
Post by: jnesselr on December 09, 2010, 07:42:03 am
I'm sure he is busy with KOS and such. The only algorithm I know is that recursive fill program that he used. To prevent that wonderful stack overflow, what you could do is essentially find the points that haven't been filled in, and go back and do the algorithm on those.  The only problem is how you would find which places still need to be filled in. I guess you could go through the stack, and delete (set to FF or something) the points that have pixels in the 4 directions (left, right, up, and down) and have their pixel filled in.  Then "collapse" the stack by going through and basically skipping over any FF data and moving the other points down.  So, if Data A is at location 1, B at location 2, and C at location 3. B is deleted, so when "collapsing", go through and copy C into B, and turn C into FF.

Basically, this clears the stack up. If it's really complicated, then not many of your points are going to get cleared, and it's going to loop forever because it can't delete anything on the stack, nor can it draw any more points. The main problem with this algorithm, though, are two-fold.

1) I haven't tested it completely. I made something like it, but I'm not sure if it was that part of the algorithm that worked.
2) Considering you are doing sub( a lot, you basically have to delete both the point and pointer off of the stack. It's quite complicated.

Not sure what else to do, though.
Title: Re: filling subroutine
Post by: SirCmpwn on December 09, 2010, 06:48:49 pm
I'm quite busy at the moment, sorry I can't help you much.  I started working on a less stack-intensive routine, but it requires a lot of RAM, and it's really slow.  It's also really complicated and hard to write.