JuliaDynamics / Agents.jl

Agent-based modeling framework in Julia
https://juliadynamics.github.io/Agents.jl/stable/
MIT License
728 stars 117 forks source link

Logo for Agents.jl #34

Closed Datseris closed 4 years ago

Datseris commented 4 years ago

Dearest @cormullion ,

I want to develop a logo for this wonderful package Agents.jl that just joined JuliaDynamics. Do you think you could give some ideas? We already had a discussion about this on Slack, but of course all is lost now...

I was thinking something like a cellular automaton whose "live" cells spelled Agents.jl :D

cormullion commented 4 years ago

Hi George! Sounds fun.

The other day I was playing with some recursive noisy grids - I thought they were pretty:

t-2019-10-09T11:27:52 307

Plenty of scope for tweaking the parameters... Might be worth investigating.

Text is going to look a bit rough at 128x128pixels ... :)

Datseris commented 4 years ago

Text is going to look a bit rough at 128x128pixels ... :)

I was surprised by this! I have found some fonts online that have quite small density of pixels, see eg: https://www.dafont.com/pixeled.font where each letter is fitted in a 4 by 6 pixel grid

Datseris commented 4 years ago

Here is a quick try:

quick powerpoint test

@kavir1698 is it easy to make a grid of squares with the plotting functionalities of Agents.jl? Because I think so far I have only seen network-like plots. How hard would it be to make plots like the "original game of life plots" with black and yellow boxes only?

kavir1698 commented 4 years ago

Well, there are functions to plot 2D cellular automata (see the first page of the docs). But there are two difficulties. One, to write "agents.jl" with that, one would have to manually determine the on and off cells. Two, the plots consist of circles, rather than squares. So it may not look as you want for the logo.

Datseris commented 4 years ago

yes that was my actual question: how hard would it be to make it plot squares instead of circles? I know finding hte squares that should be plotted will take some time :D

cormullion commented 4 years ago

I can do that easily enough - I just avoid making very small text usually... :)

kavir1698 commented 4 years ago

yes that was my actual question: how hard would it be to make it plot squares instead of circles? I know finding hte squares that should be plotted will take some time :D

I am not sure. I used GraphPlot to make those plots, and it has circles by default. Making the figure by hand should be faster. Are you thinking about an animated figure?

Datseris commented 4 years ago

Here is an updated design:

image image

maybe we can fill the currenlty blue space iwth cells that have the Julia colors, like in @cormullion 's example

cormullion commented 4 years ago

Perhaps you're looking for something like this?

Screenshot 2019-10-09 at 12 48 33
Datseris commented 4 years ago

but how? how did you make this so fast? I am still counting the god damn pixels the letters should go at!!!!!!!!!!!!!!!!!!!!!

cormullion commented 4 years ago

With squares

Screenshot 2019-10-09 at 12 53 03
cormullion commented 4 years ago

E pur si muove

life

kavir1698 commented 4 years ago

Wow!

cormullion commented 4 years ago

But you don't like that damn game of life ... :)

Datseris commented 4 years ago

god dman I AM SO SOLD IN THIS MAN. THIS I SIT I AM BUYING THOIS LOGO RIGHT NOWWWWWWWWWWWWWW

Datseris commented 4 years ago

Do you think you can share the code? My only request would be to make it more wide format, it should have similar dimensions as with the rest of the packages here: https://juliadynamics.github.io/JuliaDynamics/

Datseris commented 4 years ago

(ah also we should put the .jl , right?)

cormullion commented 4 years ago

:)

I don't think the .jl is needed, and would reduce the size a bit too much as well.

I'll do some layout work on this, but I have to go out now...

cormullion commented 4 years ago

So you can do a square icon/logo with something like this:

life

which should work at 128x128 (although not that well :))

and some kind of banner

agentsbanner

the code to make the icon is here:

https://gist.github.com/cormullion/915d4c1e9047aab7cd4ccc8f28b3c0a6

the banner is just a paste up in Affinity Designer (poor man's InDesign). Font is ChunkFive. Any fattish font will do for the icon...

Not sure where the orange and black comes from - perhaps it's from the JuliaDynamics page!

Datseris commented 4 years ago

@cormullion I get error:

julia> include("agents_cormullion.jl")
ERROR: LoadError: isinside(): EdgeException
Stacktrace:
 [1] error(::String) at .\error.jl:33
 [2] #isinside#52(::Bool, ::typeof(isinside), ::Point, ::Array{Point,1}) at C:\Users\datseris\.julia\packages\Luxor\ARqeb\src\polygons.jl:205
 [3] isinside at C:\Users\datseris\.julia\packages\Luxor\ARqeb\src\polygons.jl:187 [inlined]
 [4] makegriddedtext(::String, ::Int64, ::Int64, ::Int64, ::Int64, ::Int64) at C:\Users\datseris\GDrive\JuliaDynamics\Agents logo\agents_cormullion.jl:46
 [5] singleframe() at C:\Users\datseris\GDrive\JuliaDynamics\Agents logo\agents_cormullion.jl:104
 [6] top-level scope at C:\Users\datseris\GDrive\JuliaDynamics\Agents logo\agents_cormullion.jl:129

when running your code as-is. (I have no knowledge about Luxor I must admit)

cormullion commented 4 years ago

Hi George - I suppose you've found some rounding errors in the fonts - possibly a Mac/Windows thing.

Technically, finding whether a point is inside a polygon can give three answers: yes, no, and "it lies on the boundary". So you can change the isinside() call using the keyword:

 isinside(p, pol; allowonedge=false)

to true. Which allows points to lie on the boundary.

Datseris commented 4 years ago

Thanks. yes I had to change the font as the one you used is licensed. and super expensive.

I now use: fontface("Montserrat-Bold")

After modifying the code I now get a new error:

julia> include("agents_final.jl")
ERROR: LoadError: MethodError: no method matching getindex(::Nothing, ::Int64)
Stacktrace:
 [1] macro expansion at C:\Users\datseris\GDrive\JuliaDynamics\Agents logo\agents_final.jl:122 [inlined]
 [2] macro expansion at C:\Users\datseris\.julia\packages\Luxor\ARqeb\src\basics.jl:492 [inlined]
 [3] singleframe() at C:\Users\datseris\GDrive\JuliaDynamics\Agents logo\agents_final.jl:112
 [4] top-level scope at C:\Users\datseris\GDrive\JuliaDynamics\Agents logo\agents_final.jl:132

which points to:

image

Could it be that now isinside(pos, p; allowonedge=true) can return nothing?

cormullion commented 4 years ago

I just tried it with Montserrat-Bold, and it worked fine. A bit puzzling...

cormullion commented 4 years ago

Looks like the makegriddedtext() function is returning nothing?

Datseris commented 4 years ago

Okay, I fixed it, thanks a lot for trhe support!

cormullion commented 4 years ago

Cool, wonder what went wrong. AvenirNext is a system font on macOS... :)

Datseris commented 4 years ago

Okay I've made some progress, but I admit I am confused on changing the size . Here is how it works with default parameters:

agentsicon

after changing W=1000 I expected something that was twice as wide but with same gridding. I got:

agentsicon

So I thought that the cells are probably not equally divided. But, when I look at the code I can see that indeed there is a specific cell size:

    GoL = rand(Bool, W ÷ GRIDSQUARESIZE, H ÷ GRIDSQUARESIZE)

so why is it so "messed up"?

Datseris commented 4 years ago

Ah , this must be modified somehow:

function drawcellulargrid(a)
    rows, cols = size(a)
    t = Tiler(W, H, rows, cols, margin=0)
    for (pos, n) in t
        if a[n]
            sethue(randomjuliacolor())
            box(pos, t.tilewidth - 1, t.tilewidth - 1, :fill)
        end
    end
end

since I see no reference to the gridding here

cormullion commented 4 years ago

If you want a big background, you can use this:

using Luxor, DSP

# dimensions drawing
const W = 2000
const H = 500

const GRIDSQUARESIZE = 10

function drawcellulargrid(a)
    rows, cols = size(a)
    t = Tiler(W, H, rows, cols, margin=0)
    for (pos, n) in t
#        setopacity(mask(pos, O, W/2))
        if a[n]
            sethue([Luxor.julia_green, Luxor.julia_red,Luxor.julia_purple, Luxor.julia_blue][rand(1:end)])
            box(pos, t.tilewidth - 1, t.tileheight - 1, :fill)
        end
    end
end

function nextgeneration!(GoL, m)
    convGoL = conv(GoL, m)
    lives2 = convGoL .== 2
    lives3 = convGoL .== 3
    twoLiveNeig   =     GoL  .& lives2[2:end-1, 2:end-1]
    threeLiveNeig =     GoL  .& lives3[2:end-1, 2:end-1]
    reproduce     =  .~(GoL) .& lives3[2:end-1, 2:end-1]
    GoL[:] = twoLiveNeig .| threeLiveNeig .| reproduce
end

function graphic()
    @svg begin
        GoL = rand(Bool, H ÷ GRIDSQUARESIZE, W ÷ GRIDSQUARESIZE )
        Mfilt = [true true true; true false true; true true true]

        @layer begin
            setline(0.5)
            backgroundcolor = "grey10"
            background(backgroundcolor)
            rows, cols = size(GoL)
            update(GoL, Mfilt)
            drawcellulargrid(GoL)
        end
    end 2000 500 "/tmp/gridbackground"
end

graphic()

but I used that to make a background without the gridded text stuff.

Datseris commented 4 years ago

Yes but I also want the Agents.jl to be printed there. Seems very odd but modifying the @layer codeblock to:

        @layer begin
            setline(0.5)
            backgroundcolor = "grey10"
            background(backgroundcolor)
            rows, cols = size(GoL)
            update(GoL, Mfilt)
            drawcellulargrid(GoL)
            a = makegriddedtext("AGENTS", 110, rows, cols, W, H)
            t = Tiler(W, H, rows, cols, margin=0)
            for (pos, n) in t
                if a[n] == 1
                    sethue("orange")
                    box(pos, GRIDSQUARESIZE - 2, GRIDSQUARESIZE - 2, :fill)
                end
            end
        end

doesn't draw anything anymore :D

My goal is to achieve exactly the thing that the original animated square achieves, but instead on an arbitrary width and height grid, because I need the width to be approximately 3 times larger than the height, so that the logo has similar dimensions with the rest of the logos of JuliaDynamics.

cormullion commented 4 years ago

Yes, the banner here was supposed to do something for that space. I thought it best to not use the gridded text outside the icon cos it's not very readable...

Anyway, I think your problem is that you're calling makegriddedtext in the drawing layer. That function should run before you start your drawing proper, since you can't obtain Cairo paths unless you already have a drawing, hence the dummy drawing I used. (I originally had it running within the drawing but thought it would be useful if factored out... :) )

Datseris commented 4 years ago

Okay, after a lot of effort I have arrived at what I had envisioned:

agents_animated

The code that does this is in this gist: https://gist.github.com/Datseris/6874b2a60249499a223b35912cf6bccb

It was truly impossible for me to change the grid so that it could be non equal aspect ratio. All code collapsed once I used H and W that were not equal, and I could not for the life of me understand why. In any case, I found a solution by changing the total heigth of the squircle.

Now my question is: @cormullion is a specific command I can use to actually crop the resulting gif, so that it is not including all of that empty space above and below the logo?

cormullion commented 4 years ago

Ah I see what you’re getting at. My idea was just a quick sketch so I didn’t plan it carefully. 😀

I’ll take a look later today perhaps when I’m not on the 📱.

cormullion commented 4 years ago

I think you're just getting rows and columns mixed up - easy to do when you switch away from square things. It's Tiler(areawidth, areaheight, rows, cols, and Julia's does rows then columns (column major). I could have used Luxor.Partition perhaps...

agents_animated

(I don't like using that MN Latin/Tamil font... :) It only works for me when it's in the Julia logo...)

I commented on your Gist.

It's fun seeing you Doctors working on this stuff... (Belated congratulations, by the way!)

cormullion commented 4 years ago

Oh, I remembered why I factored out the griddedtext function - I was going to use the resulting array as a seed for the convolution... Then I'd reverse the video so that the text slowly appeared out chaos...

I'll leave that as an exercise for you experts...!

Datseris commented 4 years ago

Thanks a lot for the help @cormullion ! I now have what I think are the final versions. I've tried different fonts. My main goal was to use fonts that their g has only one hole.

Montserrat SemiBold (which, by the way, is the same font of the JuliaDynamics website)

agents_animated_Montserrat SemiBold

Orbitron (some futuristic looking font, might fit)

agents_animated_Orbitron Bold

Corbel (default Windows font)

agents_animated_Corbel Bold

@kavir1698 @cormullion what is your takes?

I think the idea you mentioned @cormullion is really amazing. But it probably does not fit best for the logo .gif, because there I would guess you would prefer to have the logo always visible...?

cormullion commented 4 years ago

I like Orbitron. Do you still like the curved outline? It’s kind of retro, I suppose, so it might look cool. Good for version 1.0!

Datseris commented 4 years ago

I like it, but to perfectly honest I would like it even more if it was true transparent instead of opaque white. But I have already asked you soooo many questions about the code I didn't want to bother you any more :P

Yeah, Orbitron is very nice I think and I also think it fits best with this curved outline. Imagine looking a game with a font like this in one of the old huge screens that naturally curve the video :D and the background really looks like space invaders :D

cormullion commented 4 years ago

yes I don't know about transparent Gifs - I could never get the working. I wrote about animated PNGs a bit here... Just dont draw a background, and it should work OK.

kavir1698 commented 4 years ago

Thank you for your efforts. These logos are all good, but I too like the Orbitron the best.