.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

how to do method "distinct<>" for objects Autodesk.AutoCAD.Geometry.Point2d ?

11 REPLIES 11
SOLVED
Reply
Message 1 of 12
joantopo
1227 Views, 11 Replies

how to do method "distinct<>" for objects Autodesk.AutoCAD.Geometry.Point2d ?

I have this:

  #region IEquatable<Points> Members
 
            public bool Equals(Points other)
            {
            if (Object.ReferenceEquals(other, null)) return false;
 
            if (Object.ReferenceEquals(this, other)) return true;
 
            return this.PointNumber.Equals(other.PointNumber);
            }
 
 
          public override int GetHashCode()
            {
             int hashDescription = this.PointNumber == null ? 0 : this.PointNumber.GetHashCode();
 
                return hashDescription;
             }
 
      #endregion

 to distinct repeat cogo points(civil 3d) about its PointNumber.

 

Now, I want the same but Point2d Collection, however it doesn´t work:

namespace toolsC3D
{
    public class Vertex : IEquatable<Vertex> 
    {
        #region IEquatable<Vertex> Members

        public bool Equals(Vertex other)
        {
            if (Object.ReferenceEquals(other, null)) return false;

            if (Object.ReferenceEquals(this, other)) return true;

            return this.punto2d.Equals(other.punto2d);
        }


        public override int GetHashCode()
        {
            int hashDescription = this.punto2d == null ? 0 : this.punto2d.GetHashCode();

            return hashDescription;
        }

        #endregion




        private Autodesk.AutoCAD.Geometry.Point2d mipunto2d = new Autodesk.AutoCAD.Geometry.Point2d(0,0);
        public Autodesk.AutoCAD.Geometry.Point2d punto2d          
        {
            get { return mipunto2d; }
            set { mipunto2d = value; }
        }

    }
}

 How can I delete all repeated location of point2D in a point2d Collection?

 

Can I do distinct with both conditions?  point2d.X and point2d.Y?

 

I have seen that Point2dCollection has IsEqual() method but I don´t know how I could use it.

Autocad C3D 2019 SP3, 2020 & 2021
Intel I9 9900K with frontal watercooler alphacool eisbaer 360 (original fans mounted in pull)- 3 fans Corsair 120 ML PRO in push.
MOBO Gygabyte Z390 Aorus Master- Corsair RGB Vengeance 64GB RAM (4x16) CL16
Nvidia Quadro RTX 4000
Samsung 970 EVO PLUS 1TB (unit C). Samsung 970 PRO 512GB (for data)
Power Supply: Corsair TX850M PLUS


Descubre mi programa VisorNET para Civil 3D:
https://apps.autodesk.com/CIV3D/es/Detail/Index?id=appstore.exchange.autodesk.com%3avisornet_windows32and64%3aes
11 REPLIES 11
Message 2 of 12
zrobert
in reply to: joantopo

Hi;

 

Try something like this. (I'm not tested this code):

 

public Point2dCollection RemoveDuplicates(Point2dCollection coll)
{
    var distinctItems = coll.ToArray().Distinct(new Point2DComparer());
    var c = distinctItems.ToArray();
    return new Point2dCollection(c);
}

class Point2DComparer : IEqualityComparer<Point2d>
{
    public bool Equals(Point2d pt1, Point2d pt2)
    {
        return System.Math.Abs(pt1.X - pt2.X) < 0.0001
            && System.Math.Abs(pt1.Y - pt2.Y) < 0.0001;
    }

    public int GetHashCode(Point2d pt)
    {
        return pt.GetHashCode();
    }
}

 

 

Message 3 of 12
_gile
in reply to: joantopo

Hi,

 

you can also use the Point2d.IsEqualTo(Point2d a) or Point2d.IsEqualTo (Point2d a, Tolerance tolerance) method.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 4 of 12
joantopo
in reply to: _gile

Yes, but I have points in the same collection. Perhaps I have to clone or copy collection and compare them to each other with IsEqual().

 

 

Autocad C3D 2019 SP3, 2020 & 2021
Intel I9 9900K with frontal watercooler alphacool eisbaer 360 (original fans mounted in pull)- 3 fans Corsair 120 ML PRO in push.
MOBO Gygabyte Z390 Aorus Master- Corsair RGB Vengeance 64GB RAM (4x16) CL16
Nvidia Quadro RTX 4000
Samsung 970 EVO PLUS 1TB (unit C). Samsung 970 PRO 512GB (for data)
Power Supply: Corsair TX850M PLUS


Descubre mi programa VisorNET para Civil 3D:
https://apps.autodesk.com/CIV3D/es/Detail/Index?id=appstore.exchange.autodesk.com%3avisornet_windows32and64%3aes
Message 5 of 12
_gile
in reply to: joantopo

You can use one of these overloaded RemoveDuplicates() extension methods.

They return a Point2d lazy sequence (IEnumerable<Point2d>) which can be iterated with foreach or converted into a Point2d array or list.

They can be called as a Point2dCollection instance method, a Point2d[] instance method or a List<Point2d> instance method.

A Tolerance can be passed as argument to be used for equality comparison, if none argument is passed the Tolerence.Global is used.

 

 

    public static class Point2dExtensions
    {
        private static Tolerance tolerance;

        public static IEnumerable<Point2d> RemoveDuplicates(this Point2dCollection source)
        {
            return source.Cast<Point2d>().RemoveDuplicates(Tolerance.Global);
        }

        public static IEnumerable<Point2d> RemoveDuplicates(this Point2dCollection source, Tolerance tolerance)
        {
            return source.Cast<Point2d>().RemoveDuplicates(tolerance);
        }

        public static IEnumerable<Point2d> RemoveDuplicates(this IEnumerable<Point2d> source)
        {
            return source.RemoveDuplicates(Tolerance.Global);
        }

        public static IEnumerable<Point2d> RemoveDuplicates(this IEnumerable<Point2d> source, Tolerance tolerance)
        {
            if (source == null)
                throw new ArgumentNullException("source");
Point2dExtensions.tolerance = tolerance; return source.Distinct(new Point2dComparer()); } class Point2dComparer : IEqualityComparer<Point2d> { public bool Equals(Point2d a, Point2d b) { return a.IsEqualTo(b, Point2dExtensions.tolerance); } public int GetHashCode(Point2d pt) { return 0; } } }

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 6 of 12
_gile
in reply to: _gile

If you want to use the HashCode in the equality comparison, you can replace the Point2dequalityComparer with this one (but I'm not sure it's more efficient).

 

        class Point2dComparer : IEqualityComparer<Point2d>
        {
            public bool Equals(Point2d a, Point2d b)
            {
                return a.IsEqualTo(b, Point2dExtensions.tolerance);
            }

            public int GetHashCode(Point2d pt)
            {
                return new Point2d(Round(pt.X), Round(pt.Y)).GetHashCode();
            }

            private double prec = Point2dExtensions.tolerance.EqualPoint * 10.0;

            private double Round(double num)
            {
                if (prec == 0.0)
                    return num;
                else
                    return Math.Floor(num / prec + 0.5) * prec;
            }
        }

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 7 of 12
joantopo
in reply to: _gile

gile, I have already tried both code amb both doesn´t work.

 

I have 12 vertex and 2 repited vertex and returns equally 12.

 

 

Autocad C3D 2019 SP3, 2020 & 2021
Intel I9 9900K with frontal watercooler alphacool eisbaer 360 (original fans mounted in pull)- 3 fans Corsair 120 ML PRO in push.
MOBO Gygabyte Z390 Aorus Master- Corsair RGB Vengeance 64GB RAM (4x16) CL16
Nvidia Quadro RTX 4000
Samsung 970 EVO PLUS 1TB (unit C). Samsung 970 PRO 512GB (for data)
Power Supply: Corsair TX850M PLUS


Descubre mi programa VisorNET para Civil 3D:
https://apps.autodesk.com/CIV3D/es/Detail/Index?id=appstore.exchange.autodesk.com%3avisornet_windows32and64%3aes
Message 8 of 12
joantopo
in reply to: joantopo

I use this, but I think that it shoud be something more efficient;

 

 public static void RemoveDuplicates(this Point2dCollection source)
        {
            for (int i = 0; i <= source.Count - 1; i++)
            {
                for (int k = 0; k <= source.Count - 1; k++)
                {
                    if (k > i)
                    {
                    if(source[i].IsEqualTo(source[k]))
                    {
                        source.RemoveAt(k);
                        k--;
                    }
                    }
                }
            }
        }

 

Autocad C3D 2019 SP3, 2020 & 2021
Intel I9 9900K with frontal watercooler alphacool eisbaer 360 (original fans mounted in pull)- 3 fans Corsair 120 ML PRO in push.
MOBO Gygabyte Z390 Aorus Master- Corsair RGB Vengeance 64GB RAM (4x16) CL16
Nvidia Quadro RTX 4000
Samsung 970 EVO PLUS 1TB (unit C). Samsung 970 PRO 512GB (for data)
Power Supply: Corsair TX850M PLUS


Descubre mi programa VisorNET para Civil 3D:
https://apps.autodesk.com/CIV3D/es/Detail/Index?id=appstore.exchange.autodesk.com%3avisornet_windows32and64%3aes
Message 9 of 12
joantopo
in reply to: zrobert

Sorry, your method works fine. Could it be possible to do the same (distinct) for point3dcollection and objectIdCollection?
Autocad C3D 2019 SP3, 2020 & 2021
Intel I9 9900K with frontal watercooler alphacool eisbaer 360 (original fans mounted in pull)- 3 fans Corsair 120 ML PRO in push.
MOBO Gygabyte Z390 Aorus Master- Corsair RGB Vengeance 64GB RAM (4x16) CL16
Nvidia Quadro RTX 4000
Samsung 970 EVO PLUS 1TB (unit C). Samsung 970 PRO 512GB (for data)
Power Supply: Corsair TX850M PLUS


Descubre mi programa VisorNET para Civil 3D:
https://apps.autodesk.com/CIV3D/es/Detail/Index?id=appstore.exchange.autodesk.com%3avisornet_windows32and64%3aes
Message 10 of 12
zrobert
in reply to: joantopo

Hi;

 

For Point3DCollection, do this changes:

 

public Point3dCollection RemoveDuplicates(Point3dCollection collection)
        {
            var a = collection.Cast<Point3d>();
            var distinctItems = a.Distinct(new Point3DComparer());
            var c = distinctItems.ToArray();
            return new Point3dCollection(c);
        }

 

private class Point3DComparer : IEqualityComparer<Point3d>
        {

            public bool Equals(Point3d pt1, Point3d pt2)
            {
                return System.Math.Abs(pt1.X - pt2.X) < 0.0001
                       && System.Math.Abs(pt1.Y - pt2.Y) < 0.0001
                       && System.Math.Abs(pt1.Z - pt2.Z) < 0.0001;
            }

            public int GetHashCode(Point3d point)
            {
                return point.GetHashCode();
            }
        }

Chears...

Message 11 of 12
zrobert
in reply to: joantopo

For ObjectIdCollection, try the same thing. ObjectIdCollection implements IList interface just

like Point3DCollection. Dont forget to change comparation logic in "SomeObject"Comparer class.

But, I think that you can avoid collection of duplicate ObjectId members...

Message 12 of 12
joantopo
in reply to: zrobert

Thanks zrobert. Yes, in some cases I can avoid do "distinct" for objectIdCollection but in other cases(for example when I get all breaklines from surface in Civil 3D, we could have repeated breaklines).
Autocad C3D 2019 SP3, 2020 & 2021
Intel I9 9900K with frontal watercooler alphacool eisbaer 360 (original fans mounted in pull)- 3 fans Corsair 120 ML PRO in push.
MOBO Gygabyte Z390 Aorus Master- Corsair RGB Vengeance 64GB RAM (4x16) CL16
Nvidia Quadro RTX 4000
Samsung 970 EVO PLUS 1TB (unit C). Samsung 970 PRO 512GB (for data)
Power Supply: Corsair TX850M PLUS


Descubre mi programa VisorNET para Civil 3D:
https://apps.autodesk.com/CIV3D/es/Detail/Index?id=appstore.exchange.autodesk.com%3avisornet_windows32and64%3aes

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost