.NET

Reply
Valued Mentor
joantopo
Posts: 675
Registered: ‎04-25-2010
Message 1 of 12 (329 Views)
Accepted Solution

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

329 Views, 11 Replies
11-07-2013 11:02 AM

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 Civil 3D 2014 +SP1 // Civil 3D 2015
Quad Core Intel i7 3770-cpu 3.40Ghz.
ssd samsung 840 pro 512gb+ssd samsung 840 pro 256 gb+1tb hdd
32gb RAM 1600 Mhz.
nVidia Quadro 2000.
Win 7 Pro 64bit

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();
}
}

 

 

Contributor
zrobert
Posts: 18
Registered: ‎08-28-2009
Message 2 of 12 (297 Views)

Re: how to do method "distinct<>" for objects Autodesk.AutoCAD

11-08-2013 02:30 AM 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();
    }
}

 

 

*Expert Elite*
_gile
Posts: 2,084
Registered: ‎04-29-2006
Message 3 of 12 (279 Views)

Re : how to do method "distinct<>" for objects Autodesk.AutoCA

11-08-2013 07:48 AM in reply to: joantopo

Hi,

 

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

Gilles Chanteau
Valued Mentor
joantopo
Posts: 675
Registered: ‎04-25-2010
Message 4 of 12 (276 Views)

Re : how to do method "distinct<>" for objects Autodesk.AutoCA

11-08-2013 07:50 AM 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 Civil 3D 2014 +SP1 // Civil 3D 2015
Quad Core Intel i7 3770-cpu 3.40Ghz.
ssd samsung 840 pro 512gb+ssd samsung 840 pro 256 gb+1tb hdd
32gb RAM 1600 Mhz.
nVidia Quadro 2000.
Win 7 Pro 64bit

*Expert Elite*
_gile
Posts: 2,084
Registered: ‎04-29-2006
Message 5 of 12 (258 Views)

Re : how to do method "distinct<>" for objects Autodesk.AutoCA

11-08-2013 02:35 PM 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
*Expert Elite*
_gile
Posts: 2,084
Registered: ‎04-29-2006
Message 6 of 12 (243 Views)

Re : how to do method "distinct<>" for objects Autodesk.AutoCA

11-09-2013 03:08 AM 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
Valued Mentor
joantopo
Posts: 675
Registered: ‎04-25-2010
Message 7 of 12 (212 Views)

Re : how to do method "distinct<>" for objects Autodesk.AutoCA

11-11-2013 07:42 AM 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 Civil 3D 2014 +SP1 // Civil 3D 2015
Quad Core Intel i7 3770-cpu 3.40Ghz.
ssd samsung 840 pro 512gb+ssd samsung 840 pro 256 gb+1tb hdd
32gb RAM 1600 Mhz.
nVidia Quadro 2000.
Win 7 Pro 64bit

Valued Mentor
joantopo
Posts: 675
Registered: ‎04-25-2010
Message 8 of 12 (206 Views)

Re : how to do method "distinct<>" for objects Autodesk.AutoCA

11-11-2013 08:01 AM 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 Civil 3D 2014 +SP1 // Civil 3D 2015
Quad Core Intel i7 3770-cpu 3.40Ghz.
ssd samsung 840 pro 512gb+ssd samsung 840 pro 256 gb+1tb hdd
32gb RAM 1600 Mhz.
nVidia Quadro 2000.
Win 7 Pro 64bit

Valued Mentor
joantopo
Posts: 675
Registered: ‎04-25-2010
Message 9 of 12 (131 Views)

Re: how to do method "distinct<>" for objects Autodesk.AutoCAD

01-29-2014 04:53 PM in reply to: zrobert
Sorry, your method works fine. Could it be possible to do the same (distinct) for point3dcollection and objectIdCollection?
Autocad Civil 3D 2014 +SP1 // Civil 3D 2015
Quad Core Intel i7 3770-cpu 3.40Ghz.
ssd samsung 840 pro 512gb+ssd samsung 840 pro 256 gb+1tb hdd
32gb RAM 1600 Mhz.
nVidia Quadro 2000.
Win 7 Pro 64bit

Contributor
zrobert
Posts: 18
Registered: ‎08-28-2009
Message 10 of 12 (104 Views)

Re: how to do method "distinct<>" for objects Autodesk.AutoCAD

01-31-2014 01:42 AM 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...

Announcements
Are you familiar with the Autodesk Expert Elites? The Expert Elite program is made up of customers that help other customers by sharing knowledge and exemplifying an engaging style of collaboration. To learn more, please visit our Expert Elite website.
Need installation help?

Start with some of our most frequented solutions or visit the Installation and Licensing Forum to get help installing your software.