Question Point3d Array Orderby

fsl88

Member
Joined
Aug 9, 2021
Messages
5
Programming Experience
Beginner
Hi

Need help in sorting my pos1[] array and saving to the sortedList[] array.

pos1 is a Point3d array,

C#:
Point3d[] pos1 = new Point3d[blockCount * 6];

My code after my pos1[] array are generated is,

C#:
var sortedList = pos1.OrderBy(p => p.X).ThenBy(p => p.Y).ToArray();

Here are the sample of my results

1628501842819.png

1628501851926.png

1628501862086.png

(0,0,0) must not appear, sometime the sorting is good, like the last picture.

The sort must be like:

X values (lowest to highest) - PRIMARY

Y values (lowest to highest) - SECONDARY



Thanks
 
Solution
It also pains me to do this, but here's the hack solution:
C#:
var sortedList = pos1.Take(j).OrderBy(p => p.X).ThenBy(x => x.Y).ToArray();
It's a kludge, and if you worked for me, I would make a point to have you re-write the code the proper way using a list instead of sticking with that array.
There's no way that sorting code can change data or create new data. There's obviously something else going on that you haven't shown us. Debug your code properly and you'll likely find it. My guess would be that you're creating the sorted array before completely filling the initial array (note that the values missing are always the last ones in the examples you've shown), but that's a guess because you haven't actually provided all the relevant information. If you debug properly and still can't find the issue, provide us with a full example that demonstrates the actual problem, including populating the initial array, sorting and then outputting.
 
When blockCount is 2, then pos1 will have 12 elements, but you seem to only be displaying nodeCount (8) items in your first screenshot. A similar situation exists for yout other 2 screenshots where blockCount * 6 is greater than nodeCount.
 
thank you guys for the reply. I have attached the file.
 

Attachments

  • Class1.txt
    7.6 KB · Views: 12
  • nodeCount.txt
    1.4 KB · Views: 13
Please post your code in code tags instead of just attaching files. For those of us reading on a mobile device, dealing with attachments is a major inconvenience and dissuade us from helping and make us just move on to the next person who needs help. It may also help to just post the relevant code and provide some explanation of what you are trying to do.
 
here below are the code for Class1.cs

C#:
using System;
using System.Linq;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
namespace SectionLedger
{
    public class SectionLegderClass
    {
        [CommandMethod("11")]
        public void SectionLedger()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            try
            {
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    BlockTable BT = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
                    TypedValue[] filterlist = new TypedValue[2];
                    filterlist[0] = new TypedValue(0, "INSERT");
                    filterlist[1] = new TypedValue(2, "blk3,blk2.5,blk2,blk1.5,blk1");
                    SelectionFilter filter = new SelectionFilter(filterlist);
                    PromptSelectionOptions opts = new PromptSelectionOptions();
                    opts.MessageForAdding = "Select entities: ";
                    PromptSelectionResult selRes = ed.GetSelection(opts, filter);
                    Point3d pt1 = new Point3d(0, 0, 0);
                    Point3d pt2 = new Point3d(0, 0, 0);
                    Point3dCollection acPts3dColl = new Point3dCollection();
                    if (selRes.Status != PromptStatus.OK)
                    {
                        ed.WriteMessage("\nNo ABC block references selected");
                        return;
                    }
                    if (selRes.Value.Count != 0)
                    {
                        SelectionSet set = selRes.Value;
                        NodeCount node = new NodeCount();
                        int nodeCount = node.nodeCount(set, tr);
                        ed.WriteMessage("\nnodeCount = " + nodeCount);
                        int blockCount = set.Count;
                        ed.WriteMessage("\nblockCount = " + blockCount);
                        int j = 0;
                        Point3d[] pos1 = new Point3d[blockCount * 6];

                        foreach (ObjectId id in set.GetObjectIds()) //scans every blocks
                        {
                            BlockReference oEnt = (BlockReference)tr.GetObject(id, OpenMode.ForRead);
                            string blockName = oEnt.Name;
                            if (blockName == "blk3")
                            {
                                pos1[j] = new Point3d(oEnt.Position.X, (oEnt.Position.Y + 190.5), 0);
                                pos1[j + 1] = new Point3d(oEnt.Position.X, (oEnt.Position.Y + 685.75), 0);
                                pos1[j + 2] = new Point3d(oEnt.Position.X, (oEnt.Position.Y + 1181.0), 0);
                                pos1[j + 3] = new Point3d(oEnt.Position.X, (oEnt.Position.Y + 1676.25), 0);
                                pos1[j + 4] = new Point3d(oEnt.Position.X, (oEnt.Position.Y + 2171.5), 0);
                                pos1[j + 5] = new Point3d(oEnt.Position.X, (oEnt.Position.Y + 2666.75), 0);
                                ed.WriteMessage("\npos1[" + j + "]" + pos1[j]);
                                ed.WriteMessage("\npos1[" + (j + 1) + "]" + pos1[j + 1]);
                                ed.WriteMessage("\npos1[" + (j + 2) + "]" + pos1[j + 2]);
                                ed.WriteMessage("\npos1[" + (j + 3) + "]" + pos1[j + 3]);
                                ed.WriteMessage("\npos1[" + (j + 4) + "]" + pos1[j + 4]);
                                ed.WriteMessage("\npos1[" + (j + 5) + "]" + pos1[j + 5]);
                                j = j + 6;
                            }
                            if (blockName == "blk2.5")
                            {
                                pos1[j] = new Point3d(oEnt.Position.X, (oEnt.Position.Y + 190.5), 0);
                                pos1[j + 1] = new Point3d(oEnt.Position.X, (oEnt.Position.Y + 685.75), 0);
                                pos1[j + 2] = new Point3d(oEnt.Position.X, (oEnt.Position.Y + 1181.0), 0);
                                pos1[j + 3] = new Point3d(oEnt.Position.X, (oEnt.Position.Y + 1676.25), 0);
                                pos1[j + 4] = new Point3d(oEnt.Position.X, (oEnt.Position.Y + 2171.5), 0);
                                ed.WriteMessage("\npos1[" + j + "]" + pos1[j]);
                                ed.WriteMessage("\npos1[" + (j + 1) + "]" + pos1[j + 1]);
                                ed.WriteMessage("\npos1[" + (j + 2) + "]" + pos1[j + 2]);
                                ed.WriteMessage("\npos1[" + (j + 3) + "]" + pos1[j + 3]);
                                ed.WriteMessage("\npos1[" + (j + 4) + "]" + pos1[j + 4]);
                                j = j + 5;
                            }
                            if (blockName == "blk2")
                            {
                                pos1[j] = new Point3d(oEnt.Position.X, (oEnt.Position.Y + 190.5), 0);
                                pos1[j + 1] = new Point3d(oEnt.Position.X, (oEnt.Position.Y + 685.75), 0);
                                pos1[j + 2] = new Point3d(oEnt.Position.X, (oEnt.Position.Y + 1181.0), 0);
                                pos1[j + 3] = new Point3d(oEnt.Position.X, (oEnt.Position.Y + 1676.25), 0);
                                ed.WriteMessage("\npos1[" + j + "]" + pos1[j]);
                                ed.WriteMessage("\npos1[" + (j + 1) + "]" + pos1[j + 1]);
                                ed.WriteMessage("\npos1[" + (j + 2) + "]" + pos1[j + 2]);
                                ed.WriteMessage("\npos1[" + (j + 3) + "]" + pos1[j + 3]);
                                j = j + 4;
                            }
                            if (blockName == "blk1.5")
                            {
                                pos1[j] = new Point3d(oEnt.Position.X, (oEnt.Position.Y + 190.5), 0);
                                pos1[j + 1] = new Point3d(oEnt.Position.X, (oEnt.Position.Y + 685.75), 0);
                                pos1[j + 2] = new Point3d(oEnt.Position.X, (oEnt.Position.Y + 1181.0), 0);
                                ed.WriteMessage("\npos1[" + j + "]" + pos1[j]);
                                ed.WriteMessage("\npos1[" + (j + 1) + "]" + pos1[j + 1]);
                                ed.WriteMessage("\npos1[" + (j + 2) + "]" + pos1[j + 2]);
                                j = j + 3;
                            }
                            if (blockName == "blk1")
                            {
                                pos1[j] = new Point3d(oEnt.Position.X, (oEnt.Position.Y + 190.5), 0);
                                pos1[j + 1] = new Point3d(oEnt.Position.X, (oEnt.Position.Y + 685.75), 0);
                                ed.WriteMessage("\npos1[" + j + "]" + pos1[j]);
                                ed.WriteMessage("\npos1[" + (j + 1) + "]" + pos1[j + 1]);
                                j = j + 2;
                            }
                        }
                        var sortedList = pos1.OrderBy(p => p.X).ThenBy(x => x.Y).ToArray();
                        for (int i = 0; i < nodeCount; i++)
                        {

                            ed.WriteMessage("\nsortedList[" + i + "]" + sortedList[i]);
                        }

                        tr.Commit();
                    }
                }
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage(ex.ToString());
            }
        }
    }
}

here below are the code for nodeCount.cs

C#:
using System;
using System.Linq;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
namespace SectionLedger
{
    public class NodeCount
    {
        public int nodeCount(SelectionSet set, Transaction tr)
        {
            int pointCount = 0;
            foreach (ObjectId id in set.GetObjectIds()) //id is the uniqe ID of each selected block
            {
                BlockReference oEnt = (BlockReference)tr.GetObject(id, OpenMode.ForRead);
                Point3d pos1 = oEnt.Position; // (x,y,z) OF EACH BLOCK SELECTED
                string blkName = oEnt.Name;
                if (blkName == "blk3")
                {
                    pointCount = 6 + pointCount;
                }
                if (blkName == "blk2.5")
                {
                    pointCount = 5 + pointCount;
                }
                if (blkName == "blk2")
                {
                    pointCount = 4 + pointCount;
                }
                if (blkName == "blk1.5")
                {
                    pointCount = 3 + pointCount;
                }
                if (blkName == "blk1")
                {
                    pointCount = 2 + pointCount;
                }
            }
            return pointCount;
        }
    }
}


1628515767182.png

I need the sortedList[0] to start on the minimum X axis value ,going to the maximum X axis value.
Then for Y axis values, it needs also to start on the minimum.
X axis must be the primary , then Y is the secondary.
The picture above can be in any combination/position of blk3 to blk1.
Thanks
 
Why are you allocating an array with:
C#:
Point3d[] pos1 = new Point3d[blockCount * 6];
and then just filling parts of the array depending on the array depending on the blkName (line 53-112)? Why not just create a list and add items to the list as needed? It feels like your C# code was originally C code that got transliterated into C#, but lost the C code's tracking of how many items were actually put into a C style array.

Update: It looks like the number of items in the array is tracked by j. So why aren't you using it?
 
Last edited:
It also pains me to do this, but here's the hack solution:
C#:
var sortedList = pos1.Take(j).OrderBy(p => p.X).ThenBy(x => x.Y).ToArray();
It's a kludge, and if you worked for me, I would make a point to have you re-write the code the proper way using a list instead of sticking with that array.
 
Solution
it worked perfectly thanks. I will also try the list approach. I only started coding for few months and its good to know that there are forums like this.
 
Back
Top Bottom