[Closed] Projecting a Plane on a Sphere
Hi guys i need a quick solution for this (math?) problem i’m facing.
The basic setup is as following: I have a Sphere which represents the earth on this i want to place a plane with a higher resolution texture of the region. My main problem right now is correctly placing the plane. I have two positions on the sphere which corresponds to the bottom left vertex of the plane and the top right vertex, these are quite easy to position But I can’t figure out how to get the other 2 vertex positions. My solution so far was to rotate my two helper objects around their midpoint and use these copies as the remaining positions but this isn’t correct as the plane doesn’t get distorted as it should be. Basically it doesn’t have the curvature of the sphere beneath it. So how do i get the positions/vectors for the other two positions?
More information: the earth is in the center of the world, the two correct coordinates came out from global mapper and this is my third maxscript and the first time i work with vectors/quats.
Another question:
I use the slerp funtion to get the right rotation for the midpoint but when i use this:
r1 = $point1.rotation
r2 = $point2.rotation
rot = slerp r1 r2 [b].5[/b]
in coordsys local rotate tPoint rot
in coordsys local move tPoint [0,0,$earth.radius]
i get a point sitting on top of the first point, when i change to
slerp r1 r2 1
i get the midpoint but i want the endpoint point2?!
The picture shows my wrong doing so far. The marked Points are the Positions which are correct. I just need the right math do get the 2 other positions.
this is fairly old and bsaed on intersectray but i still use it for hard surfaces or precise palcement
the ref obj must be an EditMesh
you select the the verts you want to project , and project them
RMB to close
there is no help file , but if it works for your needs … ask what you want
/*
-retopo tool for max
- written by cyfer
-this script is meant to help in wraping low res geometry to a higher one
-the script projects the verts in the 3 main axis (positive & negative) and additional 3 algorithms
-the most used algorithm is the vert normal , but sometimes the vpt_Cam is really usefull
-the vpt_Cam shoots a ray from the viewport to the high res geometry(ref) through the low res geometry
-simply imagine a straight line from the viewport passing through your low res geometry and hits the high res one , this is the direction of projection
*/
try(destroydialog retopo)catch()
(
global retopo, ref , thesource, pb1,MeshVertArray , i , v
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
fn att thesource ref VertDir =
(
global vertSel = polyop.getVertSelection thesource as array
for i in VertSel do
(
vertPos = polyop.getVert thesource i
DetectRay = Ray VertPos VertDir
if (Intersection = IntersectRay ref DetectRay) != undefind do
(
Polyop.SetVert thesource i Intersection.pos
)
retopo.lbl1.text= "testing_vert " + i as string
retopo.lbl1.text= "moving vert ...."
retopo.pb1.value = 100.0*i/VertSel.count
)
retopo.pb1.value = 0
retopo.lbl1.text= "Ready ! "
)
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
fn Mesh_ops thesource ref VertDir =
(
MeshVertArray = getvertselection thesource as array ;
for v in MeshVertArray do
(
Mvertpos = getVert thesource v
MV_Norm = - (getnormal thesource V)
raydetect = Ray Mvertpos MV_Norm
thehit = intersectray ref raydetect
try(setvert thesource v (thehit.pos))catch()
retopo.lbl1.text= "testing_vert " + v as string
retopo.pb1.value = 100.0*v/MeshVertArray.count
)
retopo.pb1.value = 0
retopo.lbl1.text= "Ready ! "
)
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
fn sel_Center thesource ref =
(
--gc()
--clearlistener()
converttomesh thesource
vertarr = getVertSelection thesource
vertselcenter = averageSelVertCenter thesource
p_center = point pos:(vertselcenter)
for i in vertarr do --print i
(
vertpos = getvert thesource i
pl = point pos:(vertpos)
raydetect = Ray vertpos (in coordsys pl (p_center.pos))
thehit = intersectray ref raydetect
if thehit != undefined then (setvert thesource i (thehit.pos);retopo.lbl1.text= "moving vert ...."+ thehit.pos as string )
else (retopo.lbl1.text="NO_HiT !!")
retopo.lbl1.text= "testing_vert ..." +i as string
retopo.pb1.value = 100.0*i/vertarr.count
)
--converttopoly thesource
delete $point*
retopo.pb1.value = 0
retopo.lbl1.text= "Ready ! "
)
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
/*
fn vpt_Cam = (
coordSysTM = Inverse(getViewTM())
viewDir = -coordSysTM.row3
)
*/
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
rollout retopo "Retopo" width:141 height:372
(
----------------------------------------------------------------------------------------------
--Ui Elements
----------------------------------------------------------------------------------------------
radiobuttons rdo1 "Wrap_Dir" pos:[28,63] width:84 height:158 labels:#("X_Pos", "-X_Pos", "Y_Pos", "-Y_Pos", "Z_Pos", "-Z_Pos", "Vpt_Cam", "Vert_Norm", "Verts_Center") default:0 columns:1
button btn1 "Project_Verts" pos:[14,275] width:112 height:26
progressBar pb1 "ProgressBar" pos:[14,331] width:112 height:12 value:0 color:green
GroupBox grp1 "" pos:[8,51] width:124 height:208
GroupBox grp2 "" pos:[6,264] width:126 height:87
label lbl1 "Null" pos:[7,354] width:123 height:14
pickbutton btn_ref "Pick Refrence Obj" pos:[9,15] width:122 height:30
button Clear_Buff "Clear_UnDo" pos:[14,307] width:112 height:20
checkbutton ckb1 "Auto_Project" pos:[14,227] width:112 height:24 highlightColor:(color 255 0 0)
----------------------------------------------------------------------------------------------
-- Event Handlers
----------------------------------------------------------------------------------------------
on ckb1 changed true do (rdo1.state = 0 ; btn1.visible = not btn1.visible)
----------------------------------------------------------------------------------------------
on rdo1 changed state do
(
undo on (
thesource = selection[1]
if ckb1.state == on then (
case rdo1.state of
(
1 : VertDir = [1,0,0]
2 : VertDir = [-1,0,0]
3 : VertDir = [0,1,0]
4 : VertDir = [0,-1,0]
5 : VertDir = [0,0,1]
6 : VertDir = [0,0,-1]
7 : (coordSysTM = Inverse(getViewTM()) ; viewDir = -coordSysTM.row3 ; VertDir = ViewDir)
8 : (converttomesh thesource ; VertDir = MV_Norm )
9 : (converttomesh thesource )
)
if classof thesource == editable_poly then (att thesource ref VertDir)
else (if rdo1.state == 8 do (Mesh_ops thesource ref VertDir))
if rdo1.state == 9 do (sel_Center thesource ref )
converttopoly thesource ; max modify mode ; subobjectlevel = 1
rdo1.state = 0
)
else ()
))
----------------------------------------------------------------------------------------------
on btn1 pressed do
(
--if thesource == undefined then (messagebox "Please Select Refrence object First !")
max modify mode
subobjectlevel = 1
undo on (
coordSysTM = Inverse(getViewTM())
viewDir = -coordSysTM.row3
thesource = selection[1]
--print viewDir
case rdo1.state of
(
1 : VertDir = [1,0,0]
2 : VertDir = [-1,0,0]
3 : VertDir = [0,1,0]
4 : VertDir = [0,-1,0]
5 : VertDir = [0,0,1]
6 : VertDir = [0,0,-1]
7 : VertDir = ViewDir
8 : (converttomesh thesource ; VertDir = MV_Norm)
9 : (converttomesh thesource )
)
if classof thesource == editable_poly then (att thesource ref VertDir)
else (if rdo1.state == 8 do (Mesh_ops thesource ref VertDir))
if rdo1.state == 9 do (sel_Center thesource ref)
)
converttopoly thesource ; max modify mode ; subobjectlevel = 1
)
----------------------------------------------------------------------------------------------
on btn_ref picked obj do
(
if selection != undefined do
(
btn_ref.text = obj.name
Ref = getNodeByName obj.name
)
)
----------------------------------------------------------------------------------------------
on Clear_Buff pressed do
(ClearUndoBuffer())
----------------------------------------------------------------------------------------------
on retopo rbuttondown screenpos do
(destroydialog retopo ; for i = 1 to 10 do gc(); clearlistener())-- ;
----------------------------------------------------------------------------------------------
)
createdialog retopo fgcolor:[0,255,0] style:#(#style_toolwindow)
)
I’m not really sure what you’re trying to do with question one, but look at the shperify modifier. With the pivot at 0,0,0 and the plane out on planet’s surface the you may be able to spherify it into the shape you want. Or you break out your trig functions and position each vertex on the sphere.
For the second question, there’s no such thing as “coordsys local” when referencing an object’s absolute position or rotation (notice that the spinners in the interface are always at 0,0,0 when you’re in local mode). You need to move the point to [radius, 0, 0] and then move it’s pivot to 0,0,0 and then you can do your slerp to rotate it into place.
Thinking on this some more, maybe don’t use a plane. Use a chopped squashed sphere with the same radius as the lower res one and rotate it into place.
Thanks guys. I looked into the solutions so far, but haven’t really found a solution to this problem of mine yet.
The one thing that got me thinking was to actually use a high dense sphere and cut it into the piece i need and then amend it’s rotation. But how do i fix the UVs in such a case so that they got the same projection as a simple plane? Remember i’m fairly new to mxs. And by using a plane i thought i wouldn’t need to deal with UVs.
If its still no clear what i’m trying to achieve i have found this fairly equal “thing” on Pete Drapers site. Especially the second picture shows the result i’m after. Building this system into a composite map like Pete’s version would be the second stage