classdef Polygon <shape.Shape2D
%POLYGON Create a polygon on the X-Y plane
% 
%   h = shape.Polygon returns a polygon shape on the X-Y plane
%   centered at the origin.
%
%   h = shape.Polygon(Name1=Value1,...,NameN=ValueN) creates a polygon shape 
%   with specified properties. Name is the property name and 
%   Value is the corresponding value. Properties that you do 
%   not specify retain their default values.
%
%   Polygon properties:
%
%   Name         - Name of the polygon shape. The default name is
%                  mypolygon.
%   Vertices     - Cartesian coordinates that specify the polygon in units of
%                  meters specified as a N X 3-element vector, N being the
%                  number of points.
%   Metal       - Metal assigned for the shape. The default object is
%                 'PEC' with infinite conductivity and zero
%                 thickness.
%   Color        - Face Color of the shape. The default value is 'y'.
%   Transparency - Transparency of the shape. The default value is 1.
%   EdgeColor    - Edge Color of the shape. The default value is 'k'.
%
%  polygon methods:
%
%   add           - Boolean unite operation on two shapes
%   subtract      - Boolean subtraction operation on two shapes
%   intersect     - Boolean intersection operation on two shapes
%   plus          - r1 + r2, boolean unite, equivalent to add
%   minus         - r1 - r2, boolean subtraction, equivalent to subtract
%   and           - r1&r2, boolean intersection, equivalent to intersect
%   area          - Area of shape in units of sq.m
%   show          - Visualize the shape as a filled patch
%   plot          - Visualize the shape boundary
%   mesh          - Compute/visualize the mesh of the shape
%   rotate        - Rotate the shape about an axis and an angle
%   rotateX       - Rotate the shape about X-axis with an angle
%   rotateY       - Rotate the shape about Y-axis with an angle
%   rotateZ       - Rotate the shape about Z-axis with an angle
%   translate     - Move the shape to a new location
%   scale         - Scale the size of the shape
%   imprintShape  - Imprint a 2D shape onto a custom 2D or 3D shape
%   createHole    - Create a 2D hole on the custom 2D or 3D shape
%   extrude       - Extrude a 2D shape on custom shape
%   extrudeLinear - Extrude a 2D shape linearly
%   extrudeRotate - Extrude a 2D shape by rotation
%   removeFaces   - Remove the selected faces of shape interactively
%
%   % Examples
%
%   % Example 1: % Create a polygonal shape with vertices at (-0.2,0,0),
%   % (0.4,0,0),(0,0.5,0) and  mesh it with a maximum edge length of 6 cm.
%
%   p = shape.Polygon('Vertices',[-0.2,0,0;0.4,0,0;0,0.5,0]);
%   mesh(p,MaxEdgeLength = 6e-2);
%
%   See also shape.Circle, shape.Rectangle
    
%   Copyright 2022-2023 The MathWorks, Inc.
    
properties
    Name
end

properties(Dependent)
    Vertices
end

methods
    function obj = Polygon(varargin)
        parserObj = inputParser;
        addParameter(parserObj,'Name','mypolygon');
        addParameter(parserObj,'Vertices',[ 0 0.5774  0; 0.5000  -0.2887 0;-0.5000 -0.2887 0]);
        addParameter(parserObj,'Metal','PEC');
        addParameter(parserObj,'Color','y');
        addParameter(parserObj,'Transparency',1);
        addParameter(parserObj,'EdgeColor','k');
        parse(parserObj,varargin{:});
        obj = obj@shape.Shape2D(parserObj.Results.Vertices);
        obj.Name = parserObj.Results.Name;
        obj.Vertices = parserObj.Results.Vertices;
        obj.Metal = parserObj.Results.Metal;
        obj.Color = parserObj.Results.Color;
        obj.Transparency = parserObj.Results.Transparency;
        obj.EdgeColor = parserObj.Results.EdgeColor;
    end
end


methods
    
    function set.Name(obj,propVal)
        validateattributes(propVal,{'char','string'},{'nonempty',     ...
                },class(obj),'Name') ;
        if isPropertyChanged(obj,obj.Name,propVal)
            obj.Name = propVal;
        end
    end
    
    function set.Vertices(obj,propVal)
        validateattributes(propVal,{'numeric'},{'2d',...
            'real'});
        % Check if z-coordinate exists or if it changes
        if ~isempty(propVal)
            if isequal(size(propVal,2),2)
                propVal(:,3) = 0;
            elseif ~all(propVal(~isnan(propVal(:,3)),3)==0)
                error(message('antenna:shapeerrors:Invalidcord','z coordinate'));
            end
        end
        if isPropertyChanged(obj,obj.Vertices,propVal)
            updateShape(obj,propVal)
        end
    end
    
    function propVal = get.Vertices(obj)
        propVal = obj.ShapeVertices;
    end
    
end

methods(Hidden)
    function createGeometry(obj)
        [~]=em.internal.authoring.getMultiplier(obj,obj.Vertices);
        id = isnan(obj.Vertices(:,1));
        vert = obj.Vertices;
        vert(id,:)=[];
        obj.MesherStruct.Geometry.BorderVertices = vert;  
        resetHasStructureChanged(obj);
        
        if ~isempty(obj.Thickness)
            vert = getShapeVertices(obj);
            tr = triangulation(polyshape(vert(:,1:2),'KeepCollinearPoints',true));
%             tr=triangulation(tr.ConnectivityList,[tr.Points zeros(size(tr.Points,1),1)]);
            tr=triangulation(tr.ConnectivityList,[tr.Points ones(size(tr.Points,1),1).*vert(1,3)]);
            tr=em.internal.authoring.thicken(tr,obj.Thickness);
            obj.Points = tr.Points; obj.Triangles = tr.ConnectivityList;
        end
    end
    
    function rObj = superLoad(obj,s)
        if nargin>1
            obj.Name           = s.Name;
            obj.Vertices       = s.ShapeVertices;
            rObj = superLoadShape(obj,s);
        end
    end
end

methods(Access=protected)
    function group = getPropertyGroups(obj) %#ok<MANU>
        title = '';
        propertyList = {'Name'; 'Vertices';...
             'Material';...
               'Color';'Transparency';'EdgeColor'};
        group = matlab.mixin.util.PropertyGroup(propertyList,title);
    end
    function scaleDependentProp(obj,scaling)
        obj.Vertices = obj.Vertices*scaling;        
    end
end

methods (Static = true,Hidden) % ----LOADOBJ only IMPLEMENTATION ---%
    function r = loadobj(obj)
        if isobject(obj)&& isObjectFromCurrentVersion(obj)
            r = obj;
        else
            % Create default microstrip patch
            newpolygon = shape.Polygon;
            % Populate the properties
            r = superLoad(newpolygon,obj);
        end
        r = loadobj@shape.Shape2D(r);
    end
end
end
