[RhinoCommon] How to get CPlane point


#1

Using RhinoCommon with C#. I am writing an application where the user will be working in any of the three primary views (Top, Front, or Right) and I need to get the 2D point coordinates of the point picked in one of those views (basically the CPlane coordinates shown in the status bar). Currently using the GetPoint function I get a 3D point back. How do I get the 2D CPlane point?


Detecting if an area intersects a mesh in CPlane
(Dale Fugier) #2

Hi Larry,

Converting from one coordinate system to another requires a change-of-basis transformation. Here is a simple example (I hope):

Rhino.Input.Custom.GetPoint gp = new GetPoint();
gp.SetCommandPrompt("Pick a point");
gp.Get();
if (gp.CommandResult() != Result.Success)
  return gp.CommandResult();

Rhino.Geometry.Point3d worldPoint = gp.Point();
Rhino.RhinoApp.WriteLine("World coordinates = {0}\n", worldPoint.ToString());

Rhino.Display.RhinoView view = gp.View();
if (null != view)
{
  Rhino.Geometry.Plane worldPlane = Rhino.Geometry.Plane.WorldXY;
  Rhino.Geometry.Plane localPlane = view.ActiveViewport.ConstructionPlane();
  Rhino.Geometry.Transform xform = Rhino.Geometry.Transform.ChangeBasis(worldPlane, localPlane);
  Rhino.Geometry.Point3d localPoint = worldPoint;
  localPoint.Transform(xform);
  Rhino.RhinoApp.WriteLine("Local coordinates = {0}\n", localPoint.ToString());
}

Does this help?

– Dale


#3

Dale,

Thanks for the example. That is a bit more general than I need, but it did help me to find a way to do what I wanted. Because I am stipulating that the user work in 2D in on of the three main views (Top, Front, or Right) I used the following code to get what I need:

GetPoint gp = new GetPoint();
        gp.SetCommandPrompt("Choose first focal point F of Oval");
        gp.Get();
        if (gp.CommandResult() != Result.Success)
            return gp.CommandResult();

        double x = gp.Point().X;
        double y = gp.Point().Y;
        double z = gp.Point().Z;

        RhinoView view = doc.Views.ActiveView;
        if (view == null)
            return Rhino.Commands.Result.Failure;
        string viewport_name = view.MainViewport.Name;

        Non_Imaging_Optics.NI2dPoint ptF;

        switch (viewport_name)
        {
            case "Front":
                ptF = new NI2dPoint(x, z);
                break;
            case "Top":
                ptF = new NI2dPoint(x, y);
                break;
            case "Right":
                ptF = new NI2dPoint(y, z);
                break;                
        }

        return Result.Success;

In my case, I know I need a 2D point to pass to my outside DLL, so I only need to get the 2 dimensional coordinates from the plane that is being worked in (similar to the CPlane coordinate in the status bar of the Rhino window). If there is an easier way to do this than what I am doing, I would appreciate the suggestion.

Thanks.

Larry


(Dale Fugier) #4

Hi Larry,

This is pretty much what the status bar points pane does. (Actually, it does take a shortcut, because it is just dealing with points, so the code looks more like this):

if (null != view)
{
  Rhino.Geometry.Plane localPlane = view.ActiveViewport.ConstructionPlane();
  Rhino.Geometry.Vector3d scalar = worldPoint - localPlane.Origin;
  Rhino.Geometry.Point3d localPoint = worldPoint;
  localPoint.X = scalar * localPlane.XAxis;
  localPoint.Y = scalar * localPlane.YAxis;
  localPoint.Z = scalar * localPlane.ZAxis;
  Rhino.RhinoApp.WriteLine("Local coordinates = {0}\n", localPoint.ToString());

six of one, half a dozen of the other…

Since you don’t need the Z coordinate, you can ignore that calculation.

– Dale