Post by xenovacivus on Apr 21, 2006 2:37:43 GMT -5
Seems some have had questions about this lately... Indeed it is a very interesting (and useful!!!) topic.
I just happened to have a bit of code that does exactly this. The code takes a 3D point and converts it to a 2D point, then compares it with the mouse position. It takes just a few lines of code (3) to do this, but that makes for a boring demo program... So-
I'm proud to present THE ULTIMATE 3D LINE MANIPULATION PROGRAM!!!
Use the right mouse button to rotate the scene. Use the left to move points around. Create ULTIMATE line style art!
I just happened to have a bit of code that does exactly this. The code takes a 3D point and converts it to a 2D point, then compares it with the mouse position. It takes just a few lines of code (3) to do this, but that makes for a boring demo program... So-
I'm proud to present THE ULTIMATE 3D LINE MANIPULATION PROGRAM!!!
' 3D Point Selection/Line Moving Program.
' by Ben Porter.
dim i
dim CameraMatrix# (3)(3)
dim TipAngle#, TurnAngle#, TurnAngleStart#, TipAngleStart# : TipAngle# = 30
dim MousePosition# (1)
dim ClosestPoint, ClosestPointDistance#
dim Point_3D# (2), Point_2D# (1)
dim VariousPoints# (21)(2) : for i = 0 to 21 : VariousPoints# (i)(1) = i * .2 : next
dim FieldOfView# : FieldOfView# = 60
dim AspectRatio# : AspectRatio# = (1.0*WindowWidth()) / WindowHeight ()
' 3D Point Selection Is Dependent On How The Point Is Drawn. Manually Set Up The OpenGL Projection
' To Ensure Knowlege Of Where The Point Is Drawn.
glMatrixMode (GL_PROJECTION)
glLoadIdentity ()
gluPerspective (FieldOfView#, AspectRatio#, 1, 3000)
glMatrixMode(GL_MODELVIEW)
glPointSize (4)
glLineWidth (2)
While True
CameraMatrix# = MatrixTranslate (0, 0, -10) * MatrixRotateX (TipAngle#) * MatrixRotateY (TurnAngle#)
glClear (GL_DEPTH_BUFFER_BIT or GL_COLOR_BUFFER_BIT)
glColor3f (1, 1, 1)
glLoadMatrixf (CameraMatrix#)
'// Stereotypical Draw Everything Sub
gosub DrawEverything
' UNITS ARE IMPORTANT!!! MousePosition is the mouse's position
' (imagine that...) with the bottom left hand corner bieng
' (-AspectRatio#, -1) and upper right hand bieng (AspectRatio, 1)
MousePosition# = Vec2 ((Mouse_X () - .5) * -2 * AspectRatio#, (Mouse_Y () - .5) * 2)
'// Awexome but irrelevant rotational stuff-
if Mouse_Button (MOUSE_RBUTTON) then
TurnAngle# =-MousePosition# (0) * 90 +TurnAngleStart#
TipAngle# = MousePosition# (1) * 90 +TipAngleStart#
else
TurnAngleStart# = MousePosition# (0) * 90 + TurnAngle#
TipAngleStart# = -MousePosition# (1) * 90 + TipAngle#
endif
if Mouse_Button (MOUSE_LBUTTON) then
' This Section Takes A 2D Point And Converts It To 3D- Just The
' Inverse Of The 3D Point Selection Seen Below.
Point_3D# = VariousPoints# (ClosestPoint)
Point_2D# = MousePosition#
Point_3D# = CameraMatrix# * Point_3D#
Point_3D# (0) = Point_2D# (0) * Tand (.5 * FieldOfView#) * Point_3D# (2)
Point_3D# (1) = Point_2D# (1) * Tand (.5 * FieldOfView#) * Point_3D# (2)
VariousPoints# (ClosestPoint) = RTInvert (CameraMatrix#) * Point_3D#
else
for i = 0 to 21
' Set Point_3D# To The Current Position Of The Point. The Current Position
' Of A Point Is The Point * (Any Translation/Rotation/Scaling). Conveniently,
' CameraMatrix Stores All These Things.
Point_3D# = CameraMatrix# * VariousPoints# (i)
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' The X and Y in the 3D point are proportional to the Z value- the greater '
' the z value, the greater the maximum x or y value that can be drawn on the '
' screen can be. I want a Y value between 0 and 1 (or -1 and 0, if the point '
' has a negative Y value), so I can divide the actual Y value by the largest '
' possible Y value for that Z value. To find the largest Y value, I used '
' trig to figure a right triangle with an angle half of the viewpoint, a side '
' with length z, and a side with length max Y. (specifically, a triangle through '
' (0, 0), (0, z), (y, z)). So the maximum Y value would be Tan(.5FOV)*Z. The X '
' coordinate works the same way, only instead of going from 0 to 1 X goes from 0 '
' to AspectRatio#. '
Point_2D# (0) = Point_3D# (0) / (Tand (.5 * FieldOfView#) * Point_3D# (2)) '
Point_2D# (1) = Point_3D# (1) / (Tand (.5 * FieldOfView#) * Point_3D# (2)) '
' '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
if Length (MousePosition# - Point_2D#) < ClosestPointDistance# or i = 0 then
ClosestPointDistance# = Length (MousePosition# - Point_2D#)
ClosestPoint = i
endif
next
endif
SwapBuffers ()
Wend
DrawEverything:
'//Connecting Lines
glColor3f (1, .5, 0)
glBegin (GL_LINE_STRIP)
for i = 0 to 21
glVertex3fv (VariousPoints# (i))
next
glEnd ()
'//Various Points
glColor3f (0, 1, .5)
glBegin (GL_POINTS)
for i = 0 to 21
if ClosestPoint = i then glColor3f (1, 0, 0) else glColor3f (0, 1, .5) endif
glVertex3fv (VariousPoints# (i))
next
glEnd ()
'//Grid
glColor3f (.3, .3, .3)
glBegin (GL_LINES)
for i = -5 to 5
glVertex3f (i, 0, -5)
glVertex3f (i, 0, 5)
next
glEnd ()
glBegin (GL_LINES)
for i = -5 to 5
glVertex3f (-5, 0, i)
glVertex3f (5, 0, i)
next
glEnd ()
return
Use the right mouse button to rotate the scene. Use the left to move points around. Create ULTIMATE line style art!