Return an Array

Hi All,

I have been working on a script to modify facade mullions to taper depending on the adjacent panel. I have managed to achieve the outcome I need but I had to implement some additional steps that are really redundant.

Here is the situation:

I have measured the angels and they are returned as a list, however the angles needed to be used on facade panels that are part of a 2d array. ie polygon1[0][1]

So to fix this i just combined a fake list and the angle list to create a 2d array and it all worked.


However i am sure there is a nice way to generate a 2d Array of angles from my function.

so far this is the function:

function (Polygon FacadePoly)
{
    double PAngleList = {};
    double PAngle = 0.0;
    double PAngleNext = 0.0;
    double PAngleLeft = 0.0;
 
    for (int i = 0; i < FacadePoly.Count; ++i)
    {
        for (int j = 0; j < FacadePoly[i].Count; ++j)
   
            {
            int next = j + 1 >= FacadePoly[j].Count ? j : j + 1;
            PAngle = FacadePoly[i][j].DPlane3d.Normal.AngleXY.Degrees;
            PAngleNext = FacadePoly[i][next].DPlane3d.Normal.AngleXY.Degrees;
            PAngleLeft = (PAngleNext-PAngle)/2;
            PAngleList.Add(PAngleLeft);
            }
    }
    return PAngleList;
}

The results are great, no more overlapping mullions.

Thanks

Wayne

Parents
  • Hi Wayne,

    A simple modification will change your angle list into an array:

    function (Polygon FacadePoly)
    {
        double PAngleArray = {};
        double PAngle = 0.0;
        double PAngleNext = 0.0;
        double PAngleLeft = 0.0;
     
        for (int i = 0; i < FacadePoly.Count; ++i)
        {
            double PAngleList = {};
            for (int j = 0; j < FacadePoly[i].Count; ++j)
            {
                int next = j + 1 >= FacadePoly[j].Count ? j : j + 1;
                PAngle = FacadePoly[i][j].DPlane3d.Normal.AngleXY.Degrees;
                PAngleNext = FacadePoly[i][next].DPlane3d.Normal.AngleXY.Degrees;
                PAngleLeft = (PAngleNext-PAngle)/2;
                PAngleList.Add(PAngleLeft);
            }
            PAngleArray.Add(PAngleList);
        }
        return PAngleArray;
    }
    

    HTH,

          Volker

       

    Answer Verified By: Wayne Dickerson 

  • Thanks Volker,

    That worked perfectly.

    Extending this I decided to look at the next polygon array (adjacent). We generally create facade in segments so it would be good to check to see if the last panel should reference the angle of the first panel of the adjacent polygon array.

    To this end I modified your updated script to include a if else statement. not sure if this is an efficient use of the code as it appears to repeat a bit.

    The question I have is how do you check to see if NextPoly is not Null? I have inserted a check on count. Is there a better way?

    Here is the updated code:

    function (Polygon FacadePoly, Polygon NextPoly)
    {
        double PAngleArray = {};
        double PAngle = 0.0;
        double PAngleNext = 0.0;
        double PAngleLeft = 0.0;
        Polygon IsNextPoly = {};
         
        for (int i = 0; i < FacadePoly.Count; ++i)
        {
            double PAngleList = {};
            for (int j = 0; j < FacadePoly[i].Count; ++j)
                
                {
    /// Need to find if there is a NextPoly, this will always be 0
                if (NextPoly.Count > 0)
                {
                IsNextPoly = j + 1 >= FacadePoly[j].Count ? NextPoly : FacadePoly;
                int next = j + 1 >= FacadePoly[j].Count ? 0 : j + 1;
                
                PAngle = FacadePoly[i][j].DPlane3d.Normal.AngleXY.Degrees;
                PAngleNext = IsNextPoly[i][next].DPlane3d.Normal.AngleXY.Degrees;
                PAngleLeft = (PAngleNext-PAngle)/2;
                PAngleList.Add(PAngleLeft);
                
                
                }
                else
                {
                int next = j + 1 >= FacadePoly[j].Count ? j : j + 1;
                IsNextPoly = FacadePoly;
                
                
                PAngle = FacadePoly[i][j].DPlane3d.Normal.AngleXY.Degrees;
                PAngleNext = IsNextPoly[i][next].DPlane3d.Normal.AngleXY.Degrees;
                PAngleLeft = (PAngleNext-PAngle)/2;
                PAngleList.Add(PAngleLeft);
                }
                }
                PAngleArray.Add(PAngleList);
        }
        return PAngleArray;
    }

    Thanks

    Wayne

  • Hi Wayne,

    Looks like the solution you found is valid. Congratulations! You could try to find increased efficiencies; however, fewer lines of code do not mean faster execution if the additional lines of code are executed in one branch of the logic or another. If there are additional lines of code in the same branch of logic then that usually means longer execution. Consequently, part of the clean-up is aesthetic --and facilitates code maintenance because parallel, similar code passages do not need to be maintained in parallel.

    function (Polygon FacadePoly, Polygon NextPoly)
    {
        double PAngleArray = {};
        double PAngle = 0.0;
        double PAngleNext = 0.0;
        double PAngleLeft = 0.0;
        
        // perhaps some validity check for NextPoly as done later
        bool nextPolyValid = false;
        if (NextPoly.IsList == true && NextPoly.Count > 0)
        {
            nextPolyValid = true;
        }
        
        Polygon NeighborPoly = null; 
        
        for (int i = 0; i < FacadePoly.Count; ++i)
        {
            double PAngleList = {};
            for (int j = 0; j < FacadePoly[i].Count; ++j)
            {
                // find neighboring polygon here, eliminating duplicate code
                int next = j + 1 >= FacadePoly[j].Count ? 0 : j + 1;
                if (next > 0)  // then we are within FacadePoly
                {
                    NeighborPoly = FacadePoly[i][next];
                }
                // check that we are within valid bounds of NextPoly
                else if (nextPolyValid && i < NextPoly.Count && NextPoly[i].Count > 0)
                {
                    NeighborPoly = NextPoly[i][0];
                }
                else    // the second facade has fewer rows
                {
                    break;  // skips out of this level of nesting
                }
                
                // this code only needed once
                PAngle = FacadePoly[i][j].DPlane3d.Normal.AngleXY.Degrees;
                PAngleNext = NeighborPoly.DPlane3d.Normal.AngleXY.Degrees;
                PAngleLeft = (PAngleNext-PAngle)/2;
                PAngleList.Add(PAngleLeft);
            }
            PAngleArray.Add(PAngleList);
        }
        return PAngleArray;
    }

    I have not spent excessive amounts of time on this. I made sure, though, that it does work with two neighboring polygon grids. If they are of different height, the last angle is not generated because the break; statement skips out of the inner loop without calculating an angle and, therefore not adding it to the inner list of angles. I hope that makes sense. 

    HTH,

         Volker

       

Reply
  • Hi Wayne,

    Looks like the solution you found is valid. Congratulations! You could try to find increased efficiencies; however, fewer lines of code do not mean faster execution if the additional lines of code are executed in one branch of the logic or another. If there are additional lines of code in the same branch of logic then that usually means longer execution. Consequently, part of the clean-up is aesthetic --and facilitates code maintenance because parallel, similar code passages do not need to be maintained in parallel.

    function (Polygon FacadePoly, Polygon NextPoly)
    {
        double PAngleArray = {};
        double PAngle = 0.0;
        double PAngleNext = 0.0;
        double PAngleLeft = 0.0;
        
        // perhaps some validity check for NextPoly as done later
        bool nextPolyValid = false;
        if (NextPoly.IsList == true && NextPoly.Count > 0)
        {
            nextPolyValid = true;
        }
        
        Polygon NeighborPoly = null; 
        
        for (int i = 0; i < FacadePoly.Count; ++i)
        {
            double PAngleList = {};
            for (int j = 0; j < FacadePoly[i].Count; ++j)
            {
                // find neighboring polygon here, eliminating duplicate code
                int next = j + 1 >= FacadePoly[j].Count ? 0 : j + 1;
                if (next > 0)  // then we are within FacadePoly
                {
                    NeighborPoly = FacadePoly[i][next];
                }
                // check that we are within valid bounds of NextPoly
                else if (nextPolyValid && i < NextPoly.Count && NextPoly[i].Count > 0)
                {
                    NeighborPoly = NextPoly[i][0];
                }
                else    // the second facade has fewer rows
                {
                    break;  // skips out of this level of nesting
                }
                
                // this code only needed once
                PAngle = FacadePoly[i][j].DPlane3d.Normal.AngleXY.Degrees;
                PAngleNext = NeighborPoly.DPlane3d.Normal.AngleXY.Degrees;
                PAngleLeft = (PAngleNext-PAngle)/2;
                PAngleList.Add(PAngleLeft);
            }
            PAngleArray.Add(PAngleList);
        }
        return PAngleArray;
    }

    I have not spent excessive amounts of time on this. I made sure, though, that it does work with two neighboring polygon grids. If they are of different height, the last angle is not generated because the break; statement skips out of the inner loop without calculating an angle and, therefore not adding it to the inner list of angles. I hope that makes sense. 

    HTH,

         Volker

       

Children
No Data