Author Topic: Arc from 2 endpoints and a center point  (Read 7593 times)

0 Members and 1 Guest are viewing this topic.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8702
  • AKA Daniel
Re: Arc from 2 endpoints and a center point
« Reply #15 on: June 07, 2008, 11:01:33 PM »
That's a goer Dan.
I did both versions as I thought I would be getting ucs points back from a user, but I think the op has the most common use for an arc function, feeding it wcs points. The interesting point about wcs points is that you don't know (unless there is another clue somewhere) what plane the points should be in, so you need to make a new plane for every 3 points

That is interesting, something I’ll need to goof around with. According to the docs, all coordinates must be in WCS..

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8702
  • AKA Daniel
Re: Arc from 2 endpoints and a center point
« Reply #16 on: June 07, 2008, 11:13:43 PM »
Does doing a transformby() in the instance give the desired results?

Code: [Select]
          Arc3p arcp3p1 = new Arc3p(new Point3d(0, 0, 0), new Point3d(50, 25, 0), new Point3d(100, 0, 0),true);
          arcp3p1.TransformBy(ed.CurrentUserCoordinateSystem);
          btr.AppendEntity(arcp3p1);
          tr.AddNewlyCreatedDBObject(arcp3p1,true);


MickD

  • King Gator
  • Posts: 3636
  • (x-in)->[process]->(y-out) ... simples!
Re: Arc from 2 endpoints and a center point
« Reply #17 on: June 07, 2008, 11:49:00 PM »
All coord's are stored in the db as wcs points for simplicity (else you would need to store a xform matrix as well) so all user picked points - if picked in any other ucs than wcs (quick test agains sys var) need the UcsToWcs mojo on them before creating entities, this puts the points back to wcs for correct/expected results.
hth.
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Arc from 2 endpoints and a center point
« Reply #18 on: June 08, 2008, 12:13:46 AM »
ArcFromCenter successfully adds an arc from 3 ucs points, which is then transformed.
Quote
According to the docs, all coordinates must be in WCS
In this case the 3 points are taken to be in wcs and added as such.
The other function already has the points in wcs so doesn't need to be transformed. However the normal needs to be adjusted. The odd thing I found was that I usually have to insert an entity at 0,0  change the norm, then give it the correct insertion point. With an arc seems to be above all that.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8702
  • AKA Daniel
Re: Arc from 2 endpoints and a center point
« Reply #19 on: June 11, 2008, 02:10:31 PM »
here is  another version of my class  :roll:

Code: [Select]
  public class Arc3p : Arc
  {
    // Fields
    private const double halfapi = 1.570796325;
    private const double pi = 3.14159265;

    //
    private Point3d m_startPoint;
    private Point3d m_centerPoint;
    private Point3d m_endPoint;


    // Methods
    public Arc3p()
    {
    }

    public Arc3p(Point3d startPoint, Point3d centerPoint, Point3d endPoint, bool centerIsMidPoint)
    {
      if (centerIsMidPoint)
      {
        if (CounterClockWise(startPoint, centerPoint, endPoint))
        {
          m_startPoint = endPoint;
          m_centerPoint = centerPoint;
          m_endPoint = startPoint;
        }
        else
        {
          m_startPoint = startPoint;
          m_centerPoint = centerPoint;
          m_endPoint = endPoint;
        }

        Point3d p1 = myMath(m_startPoint, m_centerPoint);
        Point3d p2 = myMath(m_centerPoint, m_endPoint);

        Point3d cp = inters(polarPoint(p1, halfapi + angle(m_startPoint, m_centerPoint), 1.0), p1,
                            polarPoint(p2, halfapi + angle(m_centerPoint, m_endPoint), 1.0), p2);

        base.Center = cp;
        base.Radius = distance(cp, m_startPoint);
        base.StartAngle = angle(cp, m_startPoint);
        base.EndAngle = angle(cp, m_endPoint);
      }
      else
      {
        base.Center = centerPoint;
        base.Radius = distance(centerPoint, startPoint);
        base.StartAngle = angle(centerPoint, startPoint);
        base.EndAngle = angle(centerPoint, endPoint);
      }
    }

    public Arc3p(IntPtr umanagedObjPtr, bool autoDelete)
      : base(umanagedObjPtr, autoDelete)
    {
    }

    public Arc3p(Point3d Center, double radius, double startAngle, double endAngle)
      : base(Center, radius, startAngle, endAngle)
    {
    }

    public Arc3p(Point3d Center, Vector3d normal, double radius, double startAngle, double endAngle)
      : base(Center, normal, radius, startAngle, endAngle)
    {
    }

    private static double angle(Point3d pt1, Point3d pt2)
    {
      CoordinateSystem3d wcs = Matrix3d.Identity.CoordinateSystem3d;
      Plane wcsplane = new Plane(wcs.Origin, wcs.Xaxis, wcs.Yaxis);
      Vector3d vec = (Vector3d)(pt2 - pt1);
      return vec.AngleOnPlane(wcsplane);
    }

    private static double distance(Point3d from, Point3d to)
    {
      return from.DistanceTo(to);
    }

    private static Point3d inters(Point3d pt1, Point3d pt2, Point3d pt3, Point3d pt4)
    {
      using (Line3d l1 = new Line3d(pt1, pt2),
                    l2 = new Line3d(pt3, pt4))
      {
        return l1.IntersectWith(l2)[0];
      }
    }

    private static Point3d myMath(Point3d pt1, Point3d pt2)
    {
      return new Point3d(pt1.X + pt2.X, pt1.Y + pt2.Y, pt1.Z + pt2.Z).DivideBy(2.0);
    }

    private static Point3d polarPoint(Point3d point, double angle, double distance)
    {
      return new Point3d(point.X + (distance * Math.Cos(angle)),
                         point.Y + (distance * Math.Sin(angle)), point.Z);
    }

    //SixFeet6
    public static bool CounterClockWise(Point3d pa, Point3d pb, Point3d pc)
    {
      return (((((pa[0] * pb[1]) - (pb[0] * pa[1])) +
                ((pb[0] * pc[1]) - (pc[0] * pb[1]))) +
                ((pc[0] * pa[1]) - (pa[0] * pc[1]))) < 0.0);

    }
  }