Author Topic: More C# Extension Methods  (Read 10727 times)

0 Members and 1 Guest are viewing this topic.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8747
  • AKA Daniel
Re: More C# Extension Methods
« Reply #15 on: December 10, 2007, 11:10:36 AM »
Hey, Dave, check this out.  It is similar to the routine you wrote.  This routine returns a negative radius if the radius is on the "left" side of the polyline.

Nice Sinc! here's a full struct for ya (i was board)... :laugh:

Code: [Select]

public struct RadiusPoint
  {
    private Point3d m_point;
    private double m_radius;

    RadiusPoint(Point3d Point, double Radius)
    {
      this.m_point = Point;
      this.m_radius = Radius;
    }

    public Point3d Point
    {
      get
      {
        return this.m_point;
      }
      set
      {
        this.m_point = value;
      }
    }

    public double Radius
    {
      get
      {
        return this.m_radius;
      }
      set
      {
        this.m_radius = value;
      }
    }

    public override int GetHashCode()
    {
      return base.GetHashCode();
    }

    public override bool Equals(object obj)
    {
      return ((obj is RadiusPoint) && (this == ((RadiusPoint)obj)));
    }

    public static bool operator ==(RadiusPoint a, RadiusPoint b)
    {
      if (a.m_point == b.m_point && a.m_radius == b.m_radius)
        return true;
      else
        return false;
    }

    public static bool operator !=(RadiusPoint a, RadiusPoint b)
    {
      if (a.m_point != b.m_point && a.m_radius != b.m_radius)
        return true;
      else
        return false;
    }

    public override string ToString()
    {
      return this.ToString(null);
    }

    public string ToString(IFormatProvider provider)
    {
      object[] args = new object[] { this.m_point, this.m_radius};
      return string.Format(provider, "({0},{1})", args);
    }
  }



Glenn R

  • Guest
Re: More C# Extension Methods
« Reply #16 on: December 10, 2007, 11:10:48 AM »
SCMD,

Neither Convert or an explicit cast is really that different, but you tend to see C types use the explicit cast syntax mostly over the use of Convert.

Be warned though, that explicit casting can cause exceptions to be thrown, but not in this case. What sinc was doing is sometimes called 'data narrowing' - stuffing a larger data type into a smaller one.

For instance, this will give a compiler error:

Code: [Select]
int myint = 30.2;

It will tell you you need an explicit cast and that one exists.
This will not give any warning or error:

Code: [Select]
int myint = (int)30.2;

The explicit cast is as if you're telling the compiler - 'hey compiler! I think I know what I'm doing!'

Cheers,
Glenn.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8747
  • AKA Daniel
Re: More C# Extension Methods
« Reply #17 on: December 10, 2007, 11:38:07 AM »
Actually you will get different answers in some cases, as Convert.ToInt32() will attempt to round where a explicit cast won’t

int i = (int)30.7;                     // = 30
int j = Convert.ToInt32(30.7); // = 31

SomeCallMeDave

  • Guest
Re: More C# Extension Methods
« Reply #18 on: December 10, 2007, 11:40:43 AM »
Glenn and Daniel,
Thanks for the explanation.

Daniel, I'm glad you pointed out the rounding.  Particularly when dealing with polyline params I would not want rounding.

Glenn R

  • Guest
Re: More C# Extension Methods
« Reply #19 on: December 10, 2007, 11:43:10 AM »
I forgot to mention the part apart rounding Dan - thanks for catching that.
The explicit cast is doing what I said though - narrowing the data field/type, so it will truncate the fractional part in this case, whereas Convert will round.

Cheers,
Glenn.

Glenn R

  • Guest
Re: More C# Extension Methods
« Reply #20 on: December 10, 2007, 12:01:16 PM »
sinc,

What does your function parameter 'double param' represent? Is it a previously derived 'curve parameter'?

Cheers,
Glenn.

sinc

  • Guest
Re: More C# Extension Methods
« Reply #21 on: December 10, 2007, 01:05:55 PM »
It is the parameter that starts the segment you want to get the radius for.

This is a utility routine that is used by other routines, and they only made the call as they "walked the polyline".  Therefore, in my code, it was always being called with a value that was an even integer (i.e., a parameter at a polyline vertex), even though the type is a double.  So I suspect I should change my code to use a cast to an int, yielding a truncation, rather than the Convert.Int32, which rounds the value.  Since my code never calls this routine with anything but integer values, I didn't notice this problem.

This routine is now part of my SincpacC3D's CurveUtil class, but I think it's a recent addition that isn't in the version posted to the web page.  I'm almost done with a major revamp of the SincpacC3D, and once it hits a relatively-stable point again, I'll post a new version of the source code that contains the revamped library classes.  The bulk of the new SincpacC3D commands will remain proprietary this time around, but I plan on releasing the base AutocadUtilites and Civil3DUtilities under a completely free license.  Eventually, I hope to break that out into a full-fledged free Autocad/Civil-3D SDK that removes much of the time-consuming "grunge" involved with working with Autodesk's low-level APIs.

And thanks for the update, Daniel...  I think I'll take what you did, and expand it a little.  Right now, there is no real test for a line segment.  Basically, for a line segment, the function returns a RadiusPoint with Radius==0.  I'd rather add an explicit flag for this, rather than having code which checks for Radius==0, which is kind of ambiguous.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8747
  • AKA Daniel
Re: More C# Extension Methods
« Reply #22 on: December 10, 2007, 01:41:24 PM »
And thanks for the update, Daniel...  I think I'll take what you did, and expand it a little.  Right now, there is no real test for a line segment.  Basically, for a line segment, the function returns a RadiusPoint with Radius==0.  I'd rather add an explicit flag for this, rather than having code which checks for Radius==0, which is kind of ambiguous.

Cool hope you can use some of it. The == and != operators are just to test the equality of the object,
so if in the future you need to do a if(RadiusPoint == RadiusPoint) nothing else

Glenn R

  • Guest
Re: More C# Extension Methods
« Reply #23 on: December 10, 2007, 03:54:12 PM »
sinc,

The reason I asked was because I didn't think the linear equation used for curves in AutoCAD, produced parameter's that directly matched a polyline vertex index count.

How about this as a basic talking point scenario:

  • ->straight line segment->[1]->curve->[2]->straight line segment->[3]


This is a 4 point polyline - maybe a simple road alignment. The numbers in brackets are the indices for the polyline.
So if you retrieved a parameter that lied between [1] and [2], even with converting to an int, I did not think that would give the correct bulge using this:

Code: [Select]
double buldge = pline.GetBulgeAt(Convert.ToInt32(param));

...as GetBulge wants a vertex index...does that make sense?

Cheers,
Glenn.

SomeCallMeDave

  • Guest
Re: More C# Extension Methods
« Reply #24 on: December 10, 2007, 04:09:12 PM »
Glenn,
All my testing shows that one gets the correct bulge (if the value was truncated and not rounded).  The parameter at vertex 1 is 1.000000.  I have yet to come across a situation where that relationship doesn't hold (at least for simple, planar lwpoly - road alignments to be precise).  I know that sort of evidence can be tricky to use.  And I have seen conversation (read arguments) elsewhere discussing this topic.


 Stacked vertices can be a problem. I always check for those before starting any parameter based calcs.

Glenn R

  • Guest
Re: More C# Extension Methods
« Reply #25 on: December 10, 2007, 04:39:34 PM »
SCMD,

Thanks for that - nice to know...I just didn't think the premise held true.

Cheers,
Glenn.