找到六边形结构的边界

时间:2015-07-11 10:51:56

标签: matlab

我有一个用于在蜂窝网络中生成六边形结构的代码,它的输入是所需的层数和半径..当输入到多个层时,它将生成7个六边形单元格,当它为2时它将产生19个细胞。现在我只需要提取六边形结构的外边界而没有任何内部六边形单元格。如何只生成六边形网络的外边界?

enter code here
d = input('Enter the distance')
radius = d/sqrt(3);% radius of each hexagon
tier = input('Enter the tier value');
%num = input('enter the value 0 or 1 : n_los=1 or los=0') ;
G = ((2*2*d)/10)+1; % value required to rearrange the matrix in 3 dim

di = 0;
global expected_bs;
expected_bs = (tier)^2 + (tier+1)^2 + (tier*(tier+1));
display(expected_bs);
global bs_cord; %base station co-ordinates
%bs_cord = zeros(expected_bs, 2);
bs_cord = [0 0];
t = linspace(0,2*pi,7);

% X and Y co-ordinates of 7 vertices for plotting hexagon. : TIER 1
x_ = [   0 0 ((sqrt(3)/2)*d) ((sqrt(3)/2)*d) 0 -((sqrt(3)/2)*d) -((sqrt(3)/2)*d)  ];
y_ = [   0 d (d/2) (-d/2) -d (-d/2) (d/2)  ];
% Hexagonal cells generation
for u=1:tier
    g_ = u*x_;% to get first hexagon structure : x coordinate
    h_ = u*y_;% to get first hexagon : y coordinate

    bs = plot_cluster(g_ , h_ , t, radius ,bs );% function defined to plot the hexagon

    if u > 1
        m_ = u* [  0 ((sqrt(3)/2)*d) ((sqrt(3)/2)*d) 0 -((sqrt(3)/2)*d) -((sqrt(3)/2)*d) 0 ];% to get hexagon in inclined direction
        n_ = u* [  d (d/2) (-d/2) -d (-d/2) (d/2) d ];

        for i=1:(u-1)
            for k=1:6
                inner_cell_x =  (((i * m_(k))+ ((u-i) * m_(k+1)))/(u)); % ratio method to obtain the coordinates of hexagon                           
                inner_cell_y =  ((i * n_(k))+ ((u-i) * n_(k+1)))/(u);
                bs = plot_cell(inner_cell_x , inner_cell_y , t, radius, bs);
            end
        end
    end
end

bs_cord = unique(bs_cord,'rows'); % base station coordinates unique func is for eliminating the replicated coordinates
有人请帮忙

1 个答案:

答案 0 :(得分:1)

我花了很长时间在这上面工作。我希望它运作良好。

秘诀是你需要摆脱任何重复的六边形,然后只计算那些顶点只有零或一个重叠的那些。

修改添加的响铃中心

function [X, Y, xe, ye, X0, Y0, outerCenter] = hexagon(varargin)
%% hexagon: A hexagon cell generating function
% Possible inputs
%   hexagon
%       Will assume a new figure is not wanted. Using this option will call
%       up inputs in the command window to get information about the cells.
%   hexagon(newFigure)
%       Where newFigure is a logical, if true the cell will be shown on a
%       new figure. If false the cell will be shown on an old figure (if
%       available). Using this option will call up inputs in the command
%       window to get information about the cells.
%   hexagon(D, tiers)
%       Where newFigure is a logical, if true the cell will be shown on a
%       new figure. If false the cell will be shown on an old figure (if
%       available).
%   hexagon(D, tiers, newFigure)
%       Where newFigure is a logical, if true the cell will be shown on a
%       new figure. If false the cell will be shown on an old figure (if
%       available).
%
% Outputs
%   X  - cell arrays of the x-coordinates of the hexagons
%   Y  - cell arrays of the y-coordinates of the hexagons
%   xe - matrix of the x-coordinates of the verticies of the edge
%   ye - matrix of the y-coordinates of the verticies of the edge
%   X  - cell arrays of the x-coordinates of the hexagons on the edge
%   Y  - cell arrays of the y-coordinates of the hexagons on the edge

%% Input parsing
    global centers
    %These are the centers of the hexagons, with the current tier.
    %Having this in allows the program to check if there is already a
    %higher tier hexagon in the same space
    centers = [0, 0, -1];

    if nargin == 0
        newFigure = 0;
        D = input('Enter the circumscribed diameter: ');
        tiers = input('Enter the tier value: ');
    elseif nargin == 1
        newFigure = varargin{1};
        D = input('Enter the circumscribed diameter: ');
        tiers = input('Enter the tier value: ');
    elseif nargin == 2
        newFigure = 0;
        D = varargin{1};
        tiers = varargin{2};
    elseif nargin == 3
        D = varargin{1};
        tiers = varargin{2};
        newFigure = varargin{3};
    elseif nargin > 3
        error('Too many input arguements entered!')
    end

    x0 = input('Enter x0: ');
    y0 = input('Enter y0: ');

%% Call first hexagon at origin
    [X, Y] = makeHexagon(x0, y0, D, tiers);


%% Find edge of cell
    [xe, ye] = findEdge(X, Y, x0, y0);

%% Find hexagons on edge
    [X0, Y0] = findEdgeHexagons(X, Y, xe, ye);

%% Outside center
    outerCenter = centers(:, [1,2]);
    outerCenter(centers(:, 3) == 0) = [];

%% Output and Plot
    disp(['A ', num2str(tiers), ' tier network of hexagons has ', num2str(numel(X)), ' elements.'])

    if newFigure
        fig = figure;
    else
        fig = gcf;
        figure(fig.Number);
    end

    T = [X; Y]; %Prepare to plot the hexagons
    plot(T{:},'LineWidth',2)
        hold on
            T = [X0; Y0]; %Prepare to plot the hexagons
            plot( T{:},'k','LineWidth',4) %Plot the edge
            plot( xe, ye,'k','LineWidth',4) %Plot the edge
        axis equal

end

%% Make the hexagons
function [X, Y] = makeHexagon(x0, y0, D, tiers)
    global centers

    X = {};
    Y = {};

%% Find out if the center has already been claimed by a higher tier
    [~, ib] = ismembertol([x0, y0], centers(:, [1,2]),'ByRows',true);

    if any(ib) && (tiers > centers(ib, 3))
        %If it's higher tiered than a previous hexagon, then update the list
        centers(ib, 3) = tiers;
    elseif any(ib) && (tiers <= centers(ib, 3))
        %If it's equal or lower tiered than a previous hexagon, then any space
        %it could explore is already claimed
        %this returns an empty cell array
        return
    else
        %It's in completely new space
        centers = [centers; x0, y0, tiers];
    end

%% Make the hexagon and its children
    %Get the verticies of the hexagon, note that there are 7 verticies to
    %close the shape
    [x, y] = hexCoords(x0, y0, D);

    %if it's not at the bottom, the hexagon needs to spawn its children
    if tiers > 0
        %The centers will alway be at 30, 90, 150, 210, 270 and 330.
        theta = linspace(0, 5*pi/3, 6)' - pi/6;
        centerX = sqrt(3)*D/2*cos(theta) + x0;
        centerY = sqrt(3)*D/2*sin(theta) + y0;

        %Call for each child, they will be one level lower
        [X, Y] = arrayfun(@(X, Y) makeHexagon(X, Y, D, tiers - 1), centerX, centerY, 'uni', 0);

        %Flatten the cell arrays this combines generations 0 to tiers - 1
        X = flatten(X);
        Y = flatten(Y);
    end

    %Combine previous generations with this generation
    X = horzcat(x, X{:});
    Y = horzcat(y, Y{:});

    %Remove any shapes that are in the same spot
    [~, i, ~] = uniquetol([X', Y'], 'ByRows', true);

    X = num2cell(X(:, i),1);
    Y = num2cell(Y(:, i),1);

end

%% Find the edge of the cell 
function [X0, Y0] = findEdge(X, Y, x0, y0)
    %Remove the extra vertex for the closed shape
    XY = cellfun(@(x, y) uniquetol([x(:), y(:)], 'ByRows', true), X, Y, 'uni', 0);

    %convert the cell array into a matrix of x and y
    XY = vertcat(XY{:});

    %Find how many times each vertex is used
    [~, uniqueVerticies, MappingIndicies] = uniquetol(XY, 'ByRows', true);
    [n, ~, ~] = histcounts(MappingIndicies, length(uniqueVerticies));

    %If it is once or twice it's on an edge
    XY = XY(uniqueVerticies(n <= 2), :);

    %Arrange the verticies angularly
    data = sortrows([atan2(XY(:,2) - y0, XY(:,1) - x0), XY]);

    %Finally, seperate them and put a final curl on it
    X0 = [data(:,2); data(1,2)];
    Y0 = [data(:,3); data(1,3)];
end

%% Find the hexagons on the edge of the cell
function [X0, Y0] = findEdgeHexagons(X, Y, xe, ye)

    i = cellfun(@(x, y) any(ismembertol([xe(:), ye(:)], [x(:), y(:)],'ByRows',true)) , X, Y);
    X0 = X(i);
    Y0 = Y(i);

end

%% Map the verticies of the hexagon
function [x, y] = hexCoords(x0, y0, D)
    %The centers will alway be at 0, 60, 120, 180, 240, 300 and 360
    %(to close the figure).
    theta = linspace(0, 2*pi, 7)';

    %Convert from polar to Cartesian coordinates 
    x = D/2 * cos(theta) + x0;
    y = D/2 * sin(theta) + y0;
end

%% Flatten the cell array and remove empty elements
function X = flatten(X)
    X = X(~cellfun(@isempty, X));
    i = cellfun(@iscell, X);

    if any(i)
        X = horzcat(X{~i}, flatten(horzcat(X{i})));
    end
end