gama-platform / gama-platform.github.io

Repository for the website of GAMA
https://gama-platform.github.io/
GNU General Public License v3.0
4 stars 2 forks source link

Some spatial operators may be clarified (overlaps, covers, ...) #159

Open tnguyenh opened 1 year ago

tnguyenh commented 1 year ago

Is your request related to a problem? Please describe.

Currently, there are several useful spatial operators, but for some of them, it's difficult to exactly understand what they exactly do or what is the difference between them, even if it's easy to get the main idea.

Those operators are:

and their collection equivalents covering, crossing, touching, overlapping, partially_ovelapping.

Some of them are very clear, but the difference between intersects, partially_overlaps, overlaps and covers maybe difficult to understand. Are the last two the same ?

Is it possible to include a figure in the documentation, that would help understand ?

tnguyenh commented 1 year ago

I will handle this in two weeks.

tnguyenh commented 11 months ago

'overlaps' and 'crosses' seem to exactly have the same behavior:

image

image

Here is the code:


* Name: spatialoperators
* Based on the internal empty template. 
* Author: Tri
* Tags: 
*/

model spatialoperators

global{
    int font_size <- 16;
    font my_font <- font("Helvetica", font_size , #plain);
    float scale <- 0.8;
    list<string> operator_list <- ["covers","overlaps","partially_overlaps","crosses","intersects","touches"];
    map<string,map<list<form>,bool>> relations;
    string current_operator <- first(operator_list);
    map<string,float> color_shift <- ["pink"::6.4,"cyan"::7.5,"yellow"::9.8,"green"::9,"purple"::9.8,"red"::5];
    map<string,float> name_shift <- ["covers"::10.6,"overlaps"::13.4,"partially_overlaps"::27.4,"crosses"::12.5,
                                        "intersects"::15.2,"touches"::12.6];
    map<string,float> frame_width <- ["covers"::0.0,"overlaps"::0,"partially_overlaps"::0,"crosses"::0,
                                        "intersects"::0,"touches"::0];
    float space_shift <- 1.6;
    geometry shape <- polygon([{0,0},{0,100},{150,100},{150,0}]);

    init{
        create form{
            shape <- rectangle(140,90);
            location <- {75,50};
            color <- #pink;
            name <- "pink";
        }
        create form{
            shape <- rectangle(20,40);
            location <- {100,50};
            color <- #cyan;
            name <- "cyan";
        }
        create form{
            shape <- circle(8);
            location <- {110,30};
            color <- #yellow;
            name <- "yellow";
        }
        create form{
            shape <- triangle(14,40) rotated_by(75);
            location <- {90,60};
            color <- rgb(150,209,69);
            name <- "green";
        }
        create form{
            shape <- square(10);
            location <- {115,75};
            color <- #purple;
            name <- "purple";
        }
        create form{
            shape <- polyline([{70,30},{110,70}]);
        //  location <- {115,75};
            color <- #red;
            name <- "red";
        }
        create legend;

        loop op over: operator_list{
            map<list<form>,bool> op_map;
            float width;
            loop f1 over: form{
                loop f2 over: form-f1{
                    switch op{
                        match "covers" {put covers(f1,f2) key: [f1,f2] in: op_map;}
                        match "overlaps" {put overlaps(f1,f2) key: [f1,f2] in: op_map;}
                        match "partially_overlaps" {put partially_overlaps(f1,f2) key: [f1,f2] in: op_map;}
                        match "crosses" {put overlaps(f1,f2) key: [f1,f2] in: op_map;}
                        match "intersects" {put intersects(f1,f2) key: [f1,f2] in: op_map;}
                        match "touches" {put touches(f1,f2) key: [f1,f2] in: op_map;}
                    }
                }
            }
            put op_map at: op in: relations;
        }

        do reset_width;
    }   

    action reset_width{
        frame_width <- ["covers"::0.0,"overlaps"::0,"partially_overlaps"::0,"crosses"::0,                                   "intersects"::0,"touches"::0];
        loop op over: operator_list{
            float width;
            loop f1 over: form{
                loop f2 over: form-f1{
                    if relations[op][[f1,f2]] {
                        width <- max(width,(name_shift[op]+color_shift[f1.name]+color_shift[f2.name]+2*space_shift)*scale);
                    }
                }
            }
            put width at: op in: frame_width;
        }
    }   
}

species legend{
    rgb color;
    point size <-{40,60};
    point window_top_left_corner <-{10,10};
    float frame_margin <- 2.5;
    float vert_shift <- 4.0;
    point shift_ini <- window_top_left_corner;
    list<form> forms;
    string name;

    aspect default{
        size <- {frame_width[current_operator]+2*frame_margin,scale*vert_shift*length(relations[current_operator] where each)+2*frame_margin-font_size/8*scale};
        draw rectangle(size) at:size/2+window_top_left_corner  color: rgb(113,98,85);
        point shift <- shift_ini+{frame_margin,frame_margin+font_size/8*scale};

        loop k over: relations[current_operator].keys{
            if relations[current_operator][k] {
                draw k[0].name at: shift color: k[0].color font: my_font;
                draw current_operator at: shift+{(color_shift[k[0].name]+space_shift)*scale,0} color:#white font: my_font;
                draw k[1].name at: shift+{(color_shift[k[0].name]+name_shift[current_operator]+2*space_shift)*scale,0} color: k[1].color font: my_font;
                shift <- shift + {0,vert_shift}*scale;
            }
        }

    }
}

species form{
    rgb color;
    string name;

    aspect default{
        draw shape color: color;
    }
}

experiment essai type: gui {
    parameter "Operator" var: current_operator among: operator_list on_change: {do update_outputs();};
    parameter "Font scale" var: scale min:0.0 max: 10.0 on_change: {ask world {do reset_width;} do update_outputs();};  
    output {
        display "Forms" type: 2d toolbar: false{ 
            species form;
            species legend aspect: default;
        }
    }
}````
lesquoyb commented 11 months ago

@ptaillandier can you provide us the documentation of the library used for those operators ? I think it could greatly help our understanding of the subtleties

tnguyenh commented 10 months ago

Here is a sample figure to illustrate the operators. What do you think about the design ?

spatialoperatorsfordoc_model_display_Forms_cycle_0_time_1698642829619

tnguyenh commented 10 months ago

I haven't been able to find examples for which there would be a difference between the operators overlaps, crosses and intersects. Any clue ?

spatialoperatorsfordoc_model_display_Forms_cycle_0_time_1698646892295 spatialoperatorsfordoc_model_display_Forms_cycle_0_time_1698646902520 spatialoperatorsfordoc_model_display_Forms_cycle_0_time_1698646907786

lesquoyb commented 10 months ago

maybe it's related to the objects' dimensions, what happens with those operators between lines or with points ?