BreakPoint

cancel
Showing results for 
Search instead for 
Did you mean: 

City In a Intensity Graph

This weekend I was so excited when I saw this js code:

for(c.width=w=99,++t,i=6e3;i--;c.getContext`2d`.fillRect(i%w,i/w|0,1-d*Z/w+s,1))for(a=i%w/50-1,s=b=1-i/4e3,X=t,Y=Z=d=1;++Z<w&(Y<6-(32<Z&27<X%w&&X/9^Z/8)*8%46||d|(s=(X&Y&Z)%3/Z,a=b=1,d=Z/w));Y-=b)X+=a

(It is originally from City In A Bottle – A 256 Byte Raycasting System)

So, I spent some time today to recreate it in LabVIEW:

CityInBottleSnippet.png

Because such ray tracing with relatively few operations looks like magic to me:

cityinbottle.gif

There may be some kinds of Rube Goldberg Code here, but it works at least. By the way, JavaScript is slightly different from the C Programming Language in terms of Operator Precedence and also logical operators' behaviors. Most of the time was spent converting this piece of code from JS to C (I learned some new old things, and I can recommend this exercise for everyone). Once it was successfully executed in C, it was more or less trivial to port it to LabVIEW. Sorry for the slightly messy diagram; I would like to see the whole thing on the same BD snipet without SubVIs. Feel free to modify or improve it, of course. Enjoy!

Download All
Message 1 of 12
(1,388 Views)

@Andrey_Dmitriev wrote:

Feel free to modify or improve it, of course. Enjoy!


Very nice!

 

What immediately comes to mind of course is that all controls belong outside the FOR loop stack. It is more effort if the compiler must assume that they can change midstream instead of allowing constant folding for the duration of the loop stack. It also makes the code cleaner to read if all control terminal are in one location instead of scattered all over the diagram.

 

I wasn't aware that bitwise operations on DBL coerce to I32. Seems somewhat random.... 😄

Message 2 of 12
(1,354 Views)

That ... is awesome!

G# - Award winning reference based OOP for LV, for free! - Qestit VIPM GitHub

Qestit Systems
Certified-LabVIEW-Developer
Message 3 of 12
(1,293 Views)

Yeah that is pretty cool. Sometimes intense math stuff like this blows my mind.  Early video game developers, and demo scene people are wizards with this type of stuff.

Message 4 of 12
(1,282 Views)

@Hooovahh wrote:

Early video game developers, and demo scene people are wizards with this type of stuff.


Imagine having to program a (pseudo) 3D racing game on an 8bit 3.58Mhz processor with 8kB RAM, but they did it (example).

 

Then there is a full chess game that was running on a 4bit processor with 80bytes (No, not kbytes!) of RAM. (see my old post here)

 

We are totally spoiled! Of course my first LabVIEW program to control a spectrometer was running on a 100Mhz Pentium 1 and I never had performance problems. 😄

Message 5 of 12
(1,269 Views)

@Hooovahh wrote:

and demo scene people are wizards with this type of stuff.


Thanks! I did a few of those (at age 12 😎)...

0 Kudos
Message 6 of 12
(1,229 Views)

Went full circle and ported the LabVIEW implementation to G Web Development Software to run in a browser 😋. See the demo page

 

CityInABottle.png

 

Used LabVIEW NXG's import from LabVIEW feature to create an NXG project, converted it to an NXG Web Module target, and then imported the NXG project to G Web so diagram was ruffled up quite a bit. It really is only useful for simple projects like this. Probably would have been quicker to rewrite by hand 😅.

 

CityInBottle.gif

Doesn't run particularly fast but G Web isn't really targeted for fast numerical processing. G Web is better suited to UI interactions and talking to backends doing any serious number crunching (or using the JSLI to call into JS for doing lots of data processing). Anyway, cool project! Was fun to play with 🙂.


Milan
Message 7 of 12
(1,117 Views)

 

kudos to you!

 

reminds me of "Creating music in one line of C code" - or caustics's 8 bit synthesizer

 

 

 

0 Kudos
Message 8 of 12
(937 Views)

I have the nagging feeling that the entire thing could be done entirely in blue (no orange wires!), but I have not tried.

0 Kudos
Message 9 of 12
(922 Views)

@altenbach wrote:

I have the nagging feeling that the entire thing could be done entirely in blue (no orange wires!), but I have not tried.


I don't think so (at least not 1:1), because a and b (X and Y increments) are fractional. But you can try.

At the beginning everything was looks pretty simple, but I spend much more time that was initially expected.

Anyway, functionally equivalent C code is below, may be will be helpful for you if you will give a try:

 

bool isThereAnythingAt(double X, double Y, int Z)
{ // The random building height comes from (X^Z)*8.
    int temp1 = (int)(X / BUILDING_WIDTH) ^ (Z / BUILDING_DEPTH);
    int temp2 = (CITY_DISTANCE < Z) & (AVENUE_WIDTH < fmod(X, (double)AVENUE_PERIOD));
    int temp3 = temp2 ? temp1 : 0;    
    int Hit = GROUND_PLANE - (temp3 *  % (BUILDING_HEIGHT + 1);
    return (Y >= Hit);
}

void verboseDraw(int t, float* data) {
    const int w = 99;
    for (int i = 6000; i--;) { // World space coordinates.
        double X = t;
        double Y = 1;
        int Z; // Ray direction in world space.
        double a = i % w / 50.0 - 1.0;
        double b = 1.0 - (double)i / 4000;
        double d = 1; // Light.
        double s = b; // Background
        for (Z = 2; Z < w; ++Z) { // Ray tracing!
            if (isThereAnythingAt(X, Y, Z)) { // We hit the model, ray tracing toward the light.
                double last_d = d;
                s = ((int)X & (int)Y & Z) % 3; // The texture.
                s /= (double)Z; // Fog.
                a = b = 1; // New direction, toward the light.
                d = (double)Z / w;
                if (last_d < 1) break; // Effectively the same as the ||d|(...) part.
            }
            X += a;
            Y -= b;
        }
        double darkness = d * Z / w - s; // Texture + lighting.
        data[i] = (float)darkness;
    }
}

 

 

0 Kudos
Message 10 of 12
(918 Views)