.NET

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

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

355 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 (323 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,114
Registered: ‎04-29-2006
Message 3 of 12 (305 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: 785
Registered: ‎04-25-2010
Message 4 of 12 (302 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,114
Registered: ‎04-29-2006
Message 5 of 12 (284 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,114
Registered: ‎04-29-2006
Message 6 of 12 (269 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: 785
Registered: ‎04-25-2010
Message 7 of 12 (238 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: 785
Registered: ‎04-25-2010
Message 8 of 12 (232 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: 785
Registered: ‎04-25-2010
Message 9 of 12 (157 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 (130 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...

Post to the Community

Have questions about Autodesk products? Ask the community.

New Post
Announcements
Are You Going To Be @ AU 2014? Feel free to drop by our AU topic post and share your plans, plug a class that you're teaching, or simply check out who else from the community might be in attendance. Ohh and don't forgot to stop by the Autodesk Help | Learn | Collaborate booths in the Exhibit Hall and meet our community team if you get a chance!