Grid 将区域除以预定义的光栅

Grid 将区域除以预定义的光栅,grid,erlang,Grid,Erlang,我有一个大网格(在图像上以灰色显示),它被分成几个块(每个块的最大宽度为3个单位)。现在我想将一个区域(在网格上用红色表示)除以相应的块 举个例子,我想要“块区域”(表示为{X,Y,Width,Height}): A:{2,3,2,1} B:{4,3,3,1} C:{7,3,1,1} D:{2,4,2,3} 我仅有的信息是网格中块的大小(在本例中为3)和区域的尺寸: {2,3,6,5}({X,Y,宽度,高度}) 有人知道如何有效地做到这一点吗?我考虑过使用mround来计算块的第一个边界

我有一个大网格(在图像上以灰色显示),它被分成几个块(每个块的最大宽度为3个单位)。现在我想将一个区域(在网格上用红色表示)除以相应的块

举个例子,我想要“块区域”(表示为{X,Y,Width,Height}):

  • A:{2,3,2,1}
  • B:{4,3,3,1}
  • C:{7,3,1,1}
  • D:{2,4,2,3}
我仅有的信息是网格中块的大小(在本例中为3)和区域的尺寸: {2,3,6,5}({X,Y,宽度,高度})


有人知道如何有效地做到这一点吗?我考虑过使用mround来计算块的第一个边界,但这会导致一个死胡同。提前谢谢

数学看起来有点奇怪,因为你从1,1开始,但这里是它的要点

  • 分别查找X/Y轴的边界(数字可除以网格中的块大小)
  • 所有尺寸均为blocksize,除最左/右/顶部/底部框外的blocksize
  • 查找这些特殊框的宽度/高度
  • 将相应的尺寸放置到相应的边界
  • 压缩两个列表
  • -出口([f/2])

    f({X,Y,Width,Height},BlockSize)->
    %除特殊情况外,所有尺寸均为Blocksize,Blocksize
    %最左侧/最右侧将具有Xfd/Xld
    %顶部/底部most将具有Yfd/Yld
    Xfd=块大小-((X-1)rem块大小),
    Xld=(X+宽度-1)rem块大小,
    Yfd=块大小-((Y-1)rem块大小),
    Yld=(Y+高度-1)rem区块大小,
    Xs=divs(X,宽度,块大小,Xfd),
    Ys=divs(Y,高度,块大小,Yfd),
    %替换最后的值
    {Lx,}=lists:last(Xs),
    Xss=lists:keyplace(Lx,1,Xs,{Lx,Xld}),
    {Ly,}=lists:last(Ys),
    Yss=lists:keyreplace(Ly,1,Ys,{Ly,Yld}),
    R=合并(Xss,Yss),
    io:格式(“~p~n”,[R])。
    合并(X,Y)->
    XY=列表:foldl(乐趣(Xx,Acc)->
    列表:foldl(乐趣(Yy,Acc1)->
    [{Xx,Yy}|Acc1]
    完,附件,Y)
    完[],X),
    列表:地图(乐趣({Xx,W},{Yy,H})->
    {Xx,Yy,W,H}
    结束,XY)。
    分区(X、W、块大小、Fd)->
    R=[{X,Fd}|[{Xs,BlockSize}| | Xs[{7,7,1,1},
    {7,4,1,3},
    {7,3,1,1},
    {4,7,3,1},
    {4,4,3,3},
    {4,3,3,1},
    {2,7,2,1},
    {2,4,2,3},
    
    {2,3,2,1}]

    为了好玩,我写了这篇文章

    -module(cluster).
    
    -compile([export_all]).
    
    -record(point, {x,y}).
    -record(area, {x,y,w,h}).
    
    area2points(A) ->
        [#point{x=X,y=Y} || 
            X <- lists:seq(A#area.x, A#area.x+ A#area.w-1), 
            Y <- lists:seq(A#area.y, A#area.y+ A#area.h-1)].
    
    points2area([]) -> empty;
    points2area(L) ->
        lists:foldl(fun(P,Acc) -> fromcorner(P,Acc) end, area(),L).
    
    area() -> #area{}.
    area(X,Y,W,H) -> #area{x=X,y=Y,w=W,h=H}.
    
    point() -> #point{}.
    point(X,Y) -> #point{x=X,y=Y}.
    
    fromcorner(#point{x=X,y=Y},#area{x=undefined,y=undefined}) -> 
        #area{x=X,y=Y,w=1,h=1};
    fromcorner(#point{x=X,y=Y},#area{x=Xa,y=Ya,w=W,h=H}) -> 
        {Xmin,Wn} = case X < Xa of
            true -> {X,Xa + W - X};
            false -> {Xa,max(W, X+1-Xa)}
        end,
        {Ymin,Hn} = case Y < Ya of
            true -> {Y,Ya + H - Y};
            false -> {Ya,max(H, Y+1-Ya)}
        end,
        #area{x=Xmin,y=Ymin,w=Wn,h=Hn}.
    
    
    split(A,L) ->
        LA = area2points(A),
        [points2area(lists:filter(fun(P) -> lists:member(P,LA) end ,area2points(X))) || X <- L].
    
    
    test() ->
        Z1 = area(1,1,3,3),
        Z2 = area(4,1,3,3),
        Z3 = area(7,1,3,3),
        Z4 = area(1,4,3,3),
        Z5 = area(4,4,3,3),
        Z6 = area(7,4,3,3),
        Z7 = area(1,7,3,3),
        Z8 = area(4,7,3,3),
        Z9 = area(7,7,3,3),
        World = [Z1,Z2,Z3,Z4,Z5,Z6,Z7,Z8,Z9],
        A = area(2,3,6,5),
        split(A,World).
    
    
    76> make:all().    
    Recompile: ../src/cluster
    up_to_date
    77> l(cluster).    
    {module,cluster}
    78> cluster:test().
    [{area,2,3,2,1},
     {area,4,3,3,1},
     {area,7,3,1,1},
     {area,2,4,2,3},
     {area,4,4,3,3},
     {area,7,4,1,3},
     {area,2,7,2,1},
     {area,4,7,3,1},
     {area,7,7,1,1}]
    79>
    
    -模块(集群)。
    -编译([export_all])。
    -记录(点,{x,y})。
    -记录(区域,{x,y,w,h})。
    区域2点(A)->
    [#点{x=x,y=y}|
    X
    列表:foldl(fun(P,Acc)->fromcorner(P,Acc)end,area(),L)。
    面积()->#面积{}。
    面积(X,Y,W,H)->#面积{X=X,Y=Y,W=W,H=H}。
    点()->#点{}。
    点(X,Y)->#点{X=X,Y=Y}。
    从角点(#点{x=x,y=y},#面积{x=undefined,y=undefined})->
    #面积{x=x,y=y,w=1,h=1};
    从角点(#点{x=x,y=y},#面积{x=Xa,y=Ya,w=w,h=h})->
    {Xmin,Wn}=情况X{X,Xa+W-X};
    假->{Xa,max(W,X+1-Xa)}
    完,,
    {Ymin,Hn}=情况Y{Y,Ya+H-Y};
    false->{Ya,max(H,Y+1-Ya)}
    完,,
    #面积{x=Xmin,y=Ymin,w=Wn,h=Hn}。
    拆分(A,L)->
    LA=区域2点(A),
    [点2区域(列表:过滤器(乐趣(P)->列表:成员(P,LA)结束,区域2点(X)))|
    Z1=面积(1,1,3,3),
    Z2=面积(4,1,3,3),
    Z3=面积(7,1,3,3),
    Z4=面积(1,4,3,3),
    Z5=面积(4,4,3,3),
    Z6=面积(7,4,3,3),
    Z7=面积(1,7,3,3),
    Z8=面积(4,7,3,3),
    Z9=面积(7,7,3,3),
    世界=[Z1,Z2,Z3,Z4,Z5,Z6,Z7,Z8,Z9],
    A=面积(2,3,6,5),
    分裂(一个世界)。
    76>生成:全部()。
    重新编译:../src/cluster
    最新
    77>l(簇)。
    {模块,集群}
    78>群集:测试()。
    [{面积,2,3,2,1},
    {区域,4,3,3,1},
    {区域,7,3,1,1},
    {面积,2,4,2,3},
    {面积,4,4,3,3},
    {区域,7,4,1,3},
    {面积,2,7,2,1},
    {区域,4,7,3,1},
    {面积,7,7,1,1}]
    79>
    
    当您计算特殊情况(Xfd、Xld、Yfd和Yld)时,出现了一些错误。当您尝试(例如)f({2,1,1,2},3)时,您会得到[{2,1,2,2}],应该是[{2,1,1,2}]。我已经搜索了很长一段时间的小错误,但没有找到它。
    -module(cluster).
    
    -compile([export_all]).
    
    -record(point, {x,y}).
    -record(area, {x,y,w,h}).
    
    area2points(A) ->
        [#point{x=X,y=Y} || 
            X <- lists:seq(A#area.x, A#area.x+ A#area.w-1), 
            Y <- lists:seq(A#area.y, A#area.y+ A#area.h-1)].
    
    points2area([]) -> empty;
    points2area(L) ->
        lists:foldl(fun(P,Acc) -> fromcorner(P,Acc) end, area(),L).
    
    area() -> #area{}.
    area(X,Y,W,H) -> #area{x=X,y=Y,w=W,h=H}.
    
    point() -> #point{}.
    point(X,Y) -> #point{x=X,y=Y}.
    
    fromcorner(#point{x=X,y=Y},#area{x=undefined,y=undefined}) -> 
        #area{x=X,y=Y,w=1,h=1};
    fromcorner(#point{x=X,y=Y},#area{x=Xa,y=Ya,w=W,h=H}) -> 
        {Xmin,Wn} = case X < Xa of
            true -> {X,Xa + W - X};
            false -> {Xa,max(W, X+1-Xa)}
        end,
        {Ymin,Hn} = case Y < Ya of
            true -> {Y,Ya + H - Y};
            false -> {Ya,max(H, Y+1-Ya)}
        end,
        #area{x=Xmin,y=Ymin,w=Wn,h=Hn}.
    
    
    split(A,L) ->
        LA = area2points(A),
        [points2area(lists:filter(fun(P) -> lists:member(P,LA) end ,area2points(X))) || X <- L].
    
    
    test() ->
        Z1 = area(1,1,3,3),
        Z2 = area(4,1,3,3),
        Z3 = area(7,1,3,3),
        Z4 = area(1,4,3,3),
        Z5 = area(4,4,3,3),
        Z6 = area(7,4,3,3),
        Z7 = area(1,7,3,3),
        Z8 = area(4,7,3,3),
        Z9 = area(7,7,3,3),
        World = [Z1,Z2,Z3,Z4,Z5,Z6,Z7,Z8,Z9],
        A = area(2,3,6,5),
        split(A,World).
    
    
    76> make:all().    
    Recompile: ../src/cluster
    up_to_date
    77> l(cluster).    
    {module,cluster}
    78> cluster:test().
    [{area,2,3,2,1},
     {area,4,3,3,1},
     {area,7,3,1,1},
     {area,2,4,2,3},
     {area,4,4,3,3},
     {area,7,4,1,3},
     {area,2,7,2,1},
     {area,4,7,3,1},
     {area,7,7,1,1}]
    79>