Point location relative to perspective viewport


#1

Is there a way to find the location of a point relative to the 2D view of the perspective viewport?

I understand cartesian coordinates and how to find the XYZ of a point in Top, Right and Front. But this doesnt give me what I’m looking for. I need the XY location of a point as viewed from the perspective viewport, not the location of the object in space.

Hope that makes sense.

~J


#2

So you want the projection of the point onto the XY plane along the camera direction vector?


#3

Yes. I believe that will give me what i need.

i know the size of the viewport is 450X450. I also know the camera XYZ points and target XYZ points.

Once again, thanks for your help!

~J


#4

Hi J11,

Does this method help?

XformWorldToScreen

Transforms a point from world coordinates to either client-area coordinates of the specified view or screen coordinates. The resulting coordinates are represented as a 2-D point.

Syntax

Rhino.XformWorldToScreen (arrPoint [, strView [, blnConvert]])

Parameters

arrPoint Required. Array. A 3-D point in world coordinates.
strView Optional. String. The title of the view. If omitted, the active view is used.
blnConvert Optional. Boolean. If omitted or False, the function returns the results as client-area coordinates of the specified view. If True, then the results are returned as screen coordinates.

Returns

Array If blnConvert is omitted or False, a 2-D point in client-area coordinates if successful.
Array If blnConvert is True, a 2-D point in screen coordinates if successful.
Null If not successful, or on error.

Example

Dim arrPoint, strView, arrPt2d

arrPoint = Array(0.0, 0.0, 0.0)

strView = Rhino.CurrentView

arrPt2d = Rhino.XformWorldToScreen(arrPoint, strView)

Rhino.Print Rhino.Pt2Str(arrPt2d)


#5

Sorry for the delay in getting back here - you could try this scriptlet on for size:

import rhinoscriptsyntax as rs

def ProjectPointToWorldXYAlongView():
    pt=rs.GetPoint("Pick point to project")
    if not pt: return
    c_view=rs.CurrentView()
    if not rs.IsViewPerspective(c_view):
        print "Active view must be a perspective projection view!" ; return
    p_pt=rs.LinePlaneIntersection([rs.ViewCamera(c_view),pt],rs.WorldXYPlane())
    rs.AddPoint(p_pt)
ProjectPointToWorldXYAlongView()

–Mitch


#6

Hello guys,
First, thank you both for taking the time to help me.

Jarek,
I ran the script and it worked. I edited it to work with my situation. It gave me values, but they dont seem to correlate to the viewport. Im including a screenshot that includes the command line results as well as the edited script.

Dim pt
Dim c_view
Dim p_pt
Dim arrBorder
Dim arrPoint
Dim arrP_pt
Dim arrPlane
Dim strView
Dim arrPt2d


Rhino.Command "-Import C:\Rendermation\Template\ringbordercurve_topangle.3dm Enter Enter"
arrBorder = Rhino.LastCreatedObjects()

'match viewport size to render 
Rhino.CurrentView "Perspective"
Rhino.Command "-viewportProperties _Size 450 450 Enter"
Rhino.Command "-viewportproperties C 0.4,-51.58,245.81 T 0.4,0.64,0.14 Enter"
Rhino.Command "-zoom s Enter"

Rhino.UnselectAllObjects

arrPoint = Rhino.PointCoordinates(Rhino.ObjectsByName("Point1", True)(0))
strView = Rhino.CurrentView

arrPt2d = Rhino.XformWorldToScreen(arrPoint, strView, False)

Rhino.Print Rhino.Pt2Str(arrPt2d)


#7

Hi Helvetosaur,

I tired to run the script but Im having problems with the syntax. I am a super novice.

Below is my attempt… I get an error on the “arrP_pt =” line
It says Type mismatch in parameter. Array required.

~Jill

Dim pt
Dim c_view
Dim p_pt
Dim arrBorder
Dim arrPoint
Dim arrP_pt
Dim arrPlane
	
	
Rhino.Command "-Import C:\Rendermation\Template\ringbordercurve_topangle.3dm Enter Enter"
arrBorder = Rhino.LastCreatedObjects()
	
	'match viewport size to render 
Rhino.CurrentView "Perspective"
Rhino.Command "-viewportProperties _Size 450 450 Enter"
Rhino.Command "-viewportproperties C 0.4,-51.58,245.81 T 0.4,0.64,0.14 Enter"
Rhino.Command "-zoom s Enter"
	
Rhino.UnselectAllObjects
	
arrPoint = Rhino.PointCoordinates(Rhino.ObjectsByName("Point1", True)(0))
arrPlane = Rhino.WorldXYPlane
	
arrP_pt = rhino.LinePlaneIntersection(arrPoint, arrPlane)
rhino.AddPoint(arrP_pt)

#8

Hi,
From what I can see you are trying to pass a point as an argument to LinePlaneIntersection, it wants a line. The line in this case is the line from the camera point - gotten with Rhino.ViewCamera(Rhino.CurrentView) - to the point in your scene. That is your “line of sight” to the point. You can then pass that line to the LinePlaneIntersection method, get the intersection of the extended line with the XY plane, and that’s your point (I hope).


#9

I see. So we create the intersection from a line that we create between the camera point and the construction plane…

I tried to edit the script, but I’m missing something.

Is the original script you wrote python? (sorry for such a question, I am a long time rhino user, and not a developer). I’m trying to understand the best place/language to start with. Currently my scripts are hacked together with duct tape and elmers glue.

~J

Sub Main()

Dim pt
Dim c_view
Dim p_pt
Dim arrBorder
Dim arrPoint
Dim arrP_pt
Dim arrPlane
Dim arrSightLine
Dim arrCameraPt


Rhino.Command "-Import C:\Rendermation\Template\ringbordercurve_topangle.3dm Enter Enter"
arrBorder = Rhino.LastCreatedObjects()

'match viewport size to render 
Rhino.CurrentView "Perspective"
Rhino.Command "-viewportProperties _Size 450 450 Enter"
Rhino.Command "-viewportproperties C 0.4,-51.58,245.81 T 0.4,0.64,0.14 Enter"
Rhino.Command "-zoom s Enter"

Rhino.UnselectAllObjects

arrPoint = Rhino.PointCoordinates(Rhino.ObjectsByName("Point1", True)(0))


'arrSightLine = Rhino.PointCoordinates(Rhino.ObjectsByName("Camera Point", True)(0))


arrCameraPt = Rhino.ViewCamera(Rhino.CurrentView)
arrPlane = Rhino.WorldXYPlane

'	 p_pt=rs.LinePlaneIntersection([rs.ViewCamera(c_view),pt],rs.WorldXYPlane())
'rs.AddPoint(p_pt)

arrSightLine = Rhino.AddLine(arrCameraPt, arrPoint)



arrP_pt = rhino.LinePlaneIntersection(arrSightLine, arrPlane)
rhino.AddPoint(arrP_pt)

End Sub


#10

That has the tendency to make them pretty sticky… :stuck_out_tongue_winking_eye:

Yes, the sample I posted is done with Python/rhinoscriptsyntax.

The idea is that your “eye” is always the camera point of the active viewport. If you look at a point object on your screen, it lies at the end of a line from the camera (your eye) to the point. If you add that line as an object in Rhino - without moving your Perspective view and assuming it’s the active view - the line will be invisible in that view, as you are looking directly down it. In the other views, the line should be visible.

All I did was find the intersection of this line (extended infinitely) and the World XY plane. That’s what LinePlaneIntersection does. The result is the point of intersection. In Perspective, the new point should also be invisible if you haven’t moved the view - it’s directly behind the original point you chose… But it lies on the XY plane.

Does that make sense?

–Mitch


#11

Hi Jill,

Can’t test the script at the moment, but all ‘looks’ correct. What values are you getting as a result?

Keep in mind that the vport coordinates system starts at upper-left corner being 0,0 and lower right 450,450 (or 449,449 ?). Does it help? If you need 0,0 in the center of the view, you may add some math to offset the coirdinates…


#12

Hi Mitch, I think we are trying to do two different things.
I may be wrong in understanding what’s needed! :wink:

Jill - do you want a 2D point coordinates in a vport XY space of your 3D point? That’s what the xform function I referenced does.


#13

Ok, I got it. I didnt realize the coordinates start in the upper left corner. I check in photoshop and the 278,158 does give the coordinates I’m looking for. Much appreciated.

I learned quite a bit from this exercise, but still dont understand what I’m doing wrong with the script above. I get an error that says 'type mismatch in parameter. Array required at this line.

arrPointLocation = Rhino.LinePlaneIntersection(arrSightLine, arrPlane)

Perhaps the Line Im trying to call actually needs to be the start point and end point as opposed to a line?
You can see the things i tried below. All give the same error.

~J

arrPointLocation = Rhino.LinePlaneIntersection(arrSightLine, arrPlane)

'arrPointLocation = Rhino.CurveSurfaceIntersection(arrSightLine, arrPlane)
'arrPointLocation = Rhino.LinePlaneIntersection([arrCameraPt, arrPoint], arrPlane())

#14

yes, it needs to be an array of start/end points, not a line object.


#15

You tried it right but used Python syntax in vbscript, thats why it didnt work.
It should have been:

arrPointLocation=Rhino.LinePlaneIntersection(array(arrCameraPt, arrPoint), arrPlane())


#16

Thanks to both of you for helping!

Much appreciated. You are both very generous with your time.

~J


#17

That’s definitely what it looks like. I guess I misunderstood the original problem (see post #2).

–Mitch


#18

Sorry guys, I didn’t explain it well.

I did however learn a lot and I think both solutions would get me to the end goal of trying to correlate a point in the viewport to a location on a rendered image.

Thanks again.

~J