Discussion specific to NXT-G, NXC, NBC, RobotC, Lejos, and more.
nxtboyiii
Posts: 366 Joined: 02 Oct 2010, 07:08
Location: Everywhere
Post
by nxtboyiii » 27 Jan 2012, 01:17
Hi,
If you download muntoo's SCR_FILE_LIB and run this program you will notice how slow the particles move.
**BTW, I did not make the algorithm for this water simulation.
I want the water particles to move faster but still smooth, but I do not know how to do it other than decreasing the # of water particles.
Here's the code:
Code: Select all
#include "SCR_File_lib.nxc"
#define NUM_OF_PARTICLES 100
task main()
{
byte map[100][64];
int px[NUM_OF_PARTICLES];
int py[NUM_OF_PARTICLES];
bool pactive[NUM_OF_PARTICLES];
int tpx,tpy;
byte ScreenMem[];
ArrayInit(ScreenMem, 0x00, 800);
ScreenMem[799] = 0x0F;
for(int c=0; c < NUM_OF_PARTICLES; c++)
{
pactive[c]=1;
}
for(int c=0; c < 24; c++)
{
px[c]=40;
py[c]=c+40;
}
for(int c=24; c < 40; c++)
{
px[c]=41;
py[c]=c+40-24;
}
for(int c=40; c < NUM_OF_PARTICLES; c++)
{
px[c]=42;
py[c]=c;
}
for(int c=60; c < NUM_OF_PARTICLES; c++)
{
px[c]=39;
py[c]=c-20;
}
for(int c=80; c < NUM_OF_PARTICLES; c++)
{
px[c]=38;
py[c]=c-40;
}
for(int c=0; c < 100; c++)
{
map[c][30]=1;
}
for(int c=0; c < 100; c++)
{
map[c][0]=1;
}
for(int c=0; c < 64; c++)
{
map[99][c]=1;
}
for(int c=0; c < 64; c++)
{
map[0][c]=1;
}
for(int c=0; c < 20; c++)
{
map[Random(98)+1][30]=0;
}
int x,y;
x=30;
y=20;
repeat(20)
{
x++;
y++;
map[x][y]=1;
}
x=20;
y=40;
repeat(20)
{
x++;
y--;
map[x][y]=1;
}
unsigned long dispAddr; //Draws the map and saves it to ScreenMem
dispAddr = DisplayDisplay();
SetDisplayDisplay(addressOf(ScreenMem));
for(int c=0; c < 100; c++)
{
for(int d=0; d < 64; d++)
{
if(map[c][d] == 1)
{
PointOut(c,d);
}
}
}
SetDisplayDisplay(dispAddr);
DisplayScreenMem(ScreenMem);
while(1)
{
SetDisplayFlags( DISPLAY_REFRESH_DISABLED );
ClearScreen();
DisplayScreenMem(ScreenMem);
for(int c=0; c < NUM_OF_PARTICLES; c++)
{
if(pactive[c])
{
tpx=px[c];
tpy=py[c];
map[tpx][tpy]=0;
if(map[tpx][tpy-1] == 0)
{
tpy--;
}
else if(map[tpx+1][tpy] == 0)
{
if(map[tpx-1][tpy] == 0)
{
tpx+=Random(3)-1;
}
else
tpx++;
}
else if(map[tpx-1][tpy] == 0)
{
tpx--;
}
PointOut(tpx,tpy);
map[tpx][tpy]=1;
px[c]=tpx;
py[c]=tpy;
}
}
SetDisplayFlags( DISPLAY_ON | DISPLAY_REFRESH );
Wait(17);
}
}
Thanks, and have a nice day,
nxtboy III
Thanks, and have a nice day,
nxtboy III
programnxt.com
mcsummation
Posts: 220 Joined: 23 Jan 2012, 17:07
Location: Round Rock, TX
Post
by mcsummation » 30 Jan 2012, 18:19
Before I bother to download your code and munge through it, what OPT level are you running in the compiler?
nxtboyiii
Posts: 366 Joined: 02 Oct 2010, 07:08
Location: Everywhere
Post
by nxtboyiii » 01 Feb 2012, 01:58
Optimization level 2.
Thanks, and have a nice day,
nxtboy III
programnxt.com
mcsummation
Posts: 220 Joined: 23 Jan 2012, 17:07
Location: Round Rock, TX
Post
by mcsummation » 01 Feb 2012, 14:44
Just how fast do you want it to run? I compiled it with the latest compiler and run it on the latest firmware and it runs about as fast as I can comfortably watch the fluid spill into the cone.
It will take me some time to analyze the code and determine what part needs to be worked on.
nxtboyiii
Posts: 366 Joined: 02 Oct 2010, 07:08
Location: Everywhere
Post
by nxtboyiii » 01 Feb 2012, 15:30
Well I want to be able to have, like 150-200 particles while still running at about as fast as the original program runs 100 particles.
Thanks, and have a nice day,
nxtboy III
programnxt.com
mcsummation
Posts: 220 Joined: 23 Jan 2012, 17:07
Location: Round Rock, TX
Post
by mcsummation » 01 Feb 2012, 15:34
Oh, OK. Now I understand. Will get back after looking at code.
spillerrec
Posts: 358 Joined: 01 Oct 2010, 06:37
Location: Denmark
Contact:
Post
by spillerrec » 01 Feb 2012, 17:19
I gave it a go too, try it out:
Code: Select all
#include "SCR_File_lib.nxc"
#define NUM_OF_PARTICLES 100
#define WIDTH (100)
#define HEIGHT (64)
#define xy( x, y ) ( (y)*WIDTH + (x) )
task main(){
byte map[ WIDTH * HEIGHT ];
int p[NUM_OF_PARTICLES];
byte ScreenMem[];
ArrayInit(ScreenMem, 0x00, 800);
ScreenMem[799] = 0x0F;
for(int c=0; c < 24; c++)
p[c] = xy( 40, c+40 );
for(int c=24; c < 40; c++)
p[c] = xy( 41, c+40-24 );
for(int c=40; c < NUM_OF_PARTICLES; c++)
p[c] = xy( 42, c );
for(int c=60; c < NUM_OF_PARTICLES; c++)
p[c] = xy( 39, c-20 );
for(int c=80; c < NUM_OF_PARTICLES; c++)
p[c] = xy( 38, c-40 );
for(int c=0; c < 100; c++)
map[ xy( c, 30 ) ] =1;
for(int c=0; c < 100; c++)
map[ xy( c, 0 ) ]=1;
for(int c=0; c < 64; c++)
map[ xy( 99, c ) ]=1;
for(int c=0; c < 64; c++)
map[ xy( 0,c ) ]=1;
for(int c=0; c < 20; c++)
map[ xy( Random(98)+1, 30 ) ]=0;
int x,y;
x=30;
y=20;
repeat(20){
x++;
y++;
map[ xy( x, y ) ]=1;
}
x=20;
y=40;
repeat(20){
x++;
y--;
map[ xy( x, y ) ]=1;
}
unsigned long dispAddr; //Draws the map and saves it to ScreenMem
dispAddr = DisplayDisplay();
SetDisplayDisplay(addressOf(ScreenMem));
for(int c=0; c < 100; c++){
for(int d=0; d < 64; d++){
if(map[ xy( c, d ) ] == 1)
PointOut(c,d);
}
}
SetDisplayDisplay(dispAddr);
DisplayScreenMem(ScreenMem);
while(1){
SetDisplayFlags( DISPLAY_ON | DISPLAY_REFRESH );
for(int c=0; c < NUM_OF_PARTICLES; c++){
int tp = p[c], org = tp;
if(map[ tp - WIDTH ] == 0)
tp -= WIDTH;
else if(map[ tp + 1 ] == 0){
if(map[ tp - 1 ] == 0)
tp += Random(3)-1;
else
tp++;
}
else if(map[ tp - 1] == 0)
tp--;
else
continue;
map[org] = 0;
map[tp]=1;
p[c]=tp;
}
SetDisplayFlags( DISPLAY_REFRESH_DISABLED );
DisplayScreenMem(ScreenMem);
int c = NUM_OF_PARTICLES;
do{
int tp = p[--c];
PointOut(tp%WIDTH,tp/WIDTH);
}while( c > 0 );
}
}
The repeated calls to PointOut is costly though, it makes up roughly half of the time for each iteration... : \
EDIT: btw, I threw out the pactive array since it was unused here...
EDIT2: I used optimization level 3 here btw
nxtboyiii
Posts: 366 Joined: 02 Oct 2010, 07:08
Location: Everywhere
Post
by nxtboyiii » 01 Feb 2012, 18:00
Wow, thanks a ton, spillerec!
I haven't tested it out yet but it looks like this could make it speed up a lot.
Thank you so much.
Have a nice day,
nxtboyIII
Thanks, and have a nice day,
nxtboy III
programnxt.com
mattallen37
Posts: 1818 Joined: 02 Oct 2010, 02:19
Location: Michigan USA
Contact:
Post
by mattallen37 » 01 Feb 2012, 18:21
Here is a slightly modified version of spillerrec's program
Code: Select all
while(1){
SetDisplayFlags( DISPLAY_ON | DISPLAY_REFRESH );
for(int c=(NUM_OF_PARTICLES-1); c+1; c--){
int tp = p[c], org = tp;
if(map[ tp - WIDTH ] == 0)
tp -= WIDTH;
else if(map[ tp + 1 ] == 0){
if(map[ tp - 1 ] == 0)
tp += Random(3)-1;
else
tp++;
}
else if(map[ tp - 1] == 0)
tp--;
else
continue;
map[org] = 0;
map[tp]=1;
p[c]=tp;
}
SetDisplayFlags( DISPLAY_REFRESH_DISABLED );
DisplayScreenMem(ScreenMem);
asm {set __PointOutArgs.Options, 0}
int c = NUM_OF_PARTICLES;
do{
int tp = p[--c];
asm{
mod __signed_stack_001main, __main_7qG2_tp_7qG2_002, 100
div __D0main, __main_7qG2_tp_7qG2_002, 100
mov __PointOutArgs.Location.X, __signed_stack_001main
mov __PointOutArgs.Location.Y, __D0main
syscall 14, __PointOutArgs
}
}while(c);
}
I don't know if it's noticeably faster, but it
is less op codes.
nxtboyiii
Posts: 366 Joined: 02 Oct 2010, 07:08
Location: Everywhere
Post
by nxtboyiii » 01 Feb 2012, 19:56
Thanks a lot for the help! Your's and spillerec's help me a lot.
Once I test it out it should be a whole lot faster.
Thanks, and have a nice day,
nxtboy III
programnxt.com
Users browsing this forum: No registered users and 6 guests