TheSwamp
Code Red => VB(A) => Topic started by: Bryco on September 04, 2006, 08:08:53 PM
-
This is a tricky one to track down.
I've got as far as the Z axis or normal is the viewdir-ucsorg normalised.
I then used the arbitrary axis algorithm to create the x-direction and y-direction
Then use the ucsorg for the translating part.
Unfortunately this doesn't compare with the ucsmatrix when the ucs is set to view.
The Z and translation are the same but the x and y fail.
The getvar viewctr translated to wcs seems to be same as the vba viewport.center but has a z value.
So I'm not quite sure if there is a point available to create a plane. Even then I'm not sure how make an x axis, perhaps it is a unit vector that goes along the viewtwist angle.
As for target, I cant believe how stingy the help is on that one.
Thanks in advance for help on this one.
-
I'm not quite sure what you want to do, do you want to create a plane/ucs based on the current view?
Remember though that the view direction vector does not necessarily point to the ucsorg a vector has no real location, only direction and length. Given the viewdir vec the AAAlgo should work fine.
-
create a plane/ucs based on the current view?
Yes to that. Mick I have been replacing the translation functions with my own and got stuck on both the acDisplayDCS translation and the current view matrix
-
What do you need to tranlate and in which direction.
I'm guessing this is for viewport alignment or similar?
-
It'll end up that way. I've been having a hard time getting the grip of views. I seem to get close then lose it.
The viewtwist doesn't help.
I started writing a sub to add 2 diagonal lines across the screen.
I can do this by translating the 4 points but cant seem to make a reliable 4x4 matrix to use transform by.
Making a ucs matrix with ucsxdir and ucsydir is easy but the view matrix is a bit confusing.
As I said I have the z just need the x
-
What you need is the 'camera' position and ocs. I'll have a look at the arx help to see what turns up.
-
Thanks Mick, Its odd how they give the target but not the camera.
-
looking at the vba help, the view centre is what you need only it gives it to you as a 2d point (as you said).
You should be able to calculate the z value of the view centre from the target point using trig with the angle of the vector etc. and the 2d centre point.
Then to get an xvec, if your view doesn't have any twist you can use the wcs z vector to create your axes.
xvec = viewdir crossproduct(wcs.zvec);
yvec = viewdir crossproduct(xvec);
or reversed if you want the matrix with z pointing away from camera.
-
I'll give that a go, but the target point only seems to line up with the view center only when you use 3dorbit as in the view is normal to the ucs. I cant really say what it is. Using the wcsZ vector is what I have done and it didn't give the right answer. Actually I use below
Function GetOcsFromNormal(N As Variant) As Variant
'N is the normal vector.
'Wy is the world Y axis, which is always (0,1,0).
'Wz is the world Z axis, which is always (0,0,1).
Dim Wy(2) As Double
Dim Wz(2) As Double
Dim Nx As Double, Ny As Double
Dim Ax, Ay, Ocs(1) As Variant
N = NormaliseVector(N)
Wy(0) = 0: Wy(1) = 1: Wy(2) = 0
Wz(0) = 0: Wz(1) = 0: Wz(2) = 1
Nx = N(0): Ny = N(1)
If (Abs(Nx) < 1 / 64) And (Abs(Ny) < 1 / 64) Then
'Ax = Wy X N (where “X” is the cross-product operator).
Ax = Crossproduct(Wy, N)
Else
Ax = Crossproduct(Wz, N)
End If
Ocs(0) = NormaliseVector(Ax)
Ay = Crossproduct(N,Ax) 'edit-had this wrong
Ocs(1) = NormaliseVector(Ay)
GetOcsFromNormal = Ocs
End Function
and perhaps I need to use the z value
-
Forgot that the x-axis must be horizontal.
It works out the GetOcsFromNormal function gives a correct answer but the x and y vectors need to be rotated by minus the viewtwist amount around the z (viewdir). I have a matrix that does that, rotates around a vector that I adapted to vba but couldn't possibly work out myself.But it seems like a it could be done with a little less math.
Anyway I can at least match a view ucs matrix now.
-
nice one.
The simplest way to rotate around a vector is to move the ucs so that the vector is the z axis (rotation axis), it doesn't matter which way the x and y are pointing as long as they're still orthoganal as you are only rotating around the z axis by a given amount regardless.
-
To use this matrix I still need to find some magic number.
I think it is tied into the center of the 3d view mentioned in acad help
When the 3DORBIT command is active, the default target location is the center of the 3D view, which is not always the center of the objects you are viewing
Whatever that is.
-
Here is an example of the confusion I'm having.
Run this sub then run the 3dorbit command.
The aim is to find the center of the 3dorbit,
It works great for a while.
Run it again and it's no good.
Sub OrbitCenter()
Dim C, T, O, P As AcadPoint
Dim Util As AcadUtility
Set Util = ThisDrawing.Utility
ThisDrawing.SetVariable "PDSIZE", 0.5
ThisDrawing.SetVariable "PDMODE", 35
C = ThisDrawing.GetVariable("viewctr")
C = Util.TranslateCoordinates(C, acUCS, acWorld, 0)
T = ThisDrawing.GetVariable("target")
T = Util.TranslateCoordinates(T, acUCS, acWorld, 0)
Set P = ThisDrawing.ModelSpace.AddPoint(C)
P.color = acGreen
Set P = ThisDrawing.ModelSpace.AddPoint(T)
Dim dMid(2) As Double
dMid(0) = (C(0) + T(0)) / 2
dMid(1) = (C(1) + T(1)) / 2
dMid(2) = (C(2) + T(2)) / 2
Set P = ThisDrawing.ModelSpace.AddPoint(dMid)
P.color = acYellow
ThisDrawing.ModelSpace.AddLine C, T
End Sub
In a new drawing the target getvar is 0,0,0
type camera and
Command: ca CAMERA Specify new camera position <6.0000,4.8571,18.3799>:
Specify new camera target <6.0000,4.8571,0.0000>: Regenerating model.
Since I'm in an inch dwg the x and y values are the center of the limits (12,9) (I presume the actual number varies with resolution).
A new target value seems to start with the old z value and take the screen center x and y.
But where does the 18.3799 come from?
-
Yep, that's a hard one. The view target probably gets transformed when zooming in and out and panning with an internal function so really you will never know where the target will be unless you ask for it or give it to your function (perhaps by giving it the centre of your geometry's bounding box). Notice that while zooming using the mouse wheel and moving the mouse it also pans which effectively moves the target.
ie, I think the target moves with the camera unless you are zooming which then moves the target away, 'tis a triicky one without seeing how it ticks. Maybe worth a look at seeing if that is indded what happens??
-
I've been looking for the relationship of the target in the camera command..
In vba there is no camera but there is a target which doesnt update with A Pan or zoom.
The target in the camera command does update as you know.
So far the z value seems to be something like 0.52855 times the viewsize, I havent related that to twisted views yet.
-
I've been looking for the relationship of the target in the camera command..
In vba there is no camera but there is a target which doesnt update with A Pan or zoom.
...
sorry, didn't mean the camera command as such, just the camera/view in general.
It will be hard to find out as the target in the scenario I put up before as the camera/view can see beyond and before the target as it can see the whole graphics viewing volume (unless it's clipped which is effectively reducing the viewing volume). In these cases the target isn't really 'tied' to anything as it doesn't matter.
If I needed an accurate view the best way would be to 'tie' it to some geometry some how so you can update it if required, grabbing the target does not seem to be reliable at all.
I have to do this myself, I currently have a viewing tool to set a clipped view on a 3d solid given a ucs z value and I have the same problem. If I use the target, the new view when set could be anywhere and I have to zoom or pan to find the object I want to see a detail of, this is a throw back from using the target (which is not at what I was looking at). To get around this I will be getting the bbox of the object, find the centre then use that as the target. I will then set my view rect to be a bit larger than the bbox which will (hopefully) set the zoom.
hth.
-
Well I have the target.
Perhaps this will work for other languages as it uses setvars.
It seems the Distance (or Z value in a 2d dwg) is the z value of the viewctr tanslated to display.
Since the Center of the display is the target, this makes sense.
The viewctr value is reliable (updates with pan and zoom)
In a 2d drawing you will find the x and y of the target are the x and y of the viewctr translated to world.
This property gives an updated Target in Wcs
Property Get VT() As Variant 'Target 'no update
'This gives an updated Target in Wcs
Dim Tar(2) As Double
Dim C, Cen, dir
Dim Dist As Double
C = ThisDrawing.GetVariable("viewctr")
Cen = ToWcs(C)
dir = VD
C = UToD(C)
Dist = -C(2)
Tar(0) = Cen(0) + Dist * dir(0)
Tar(1) = Cen(1) + Dist * dir(1)
Tar(2) = Cen(2) + Dist * dir(2)
VT = Tar
End Property
Function ToUcs(Pt As Variant) As Variant
ToUcs = ThisDrawing.Utility.TranslateCoordinates(Pt, acWorld, acUCS, False)
End Function
Function ToWcs(Pt As Variant) As Variant
ToWcs = ThisDrawing.Utility.TranslateCoordinates(Pt, acUCS, acWorld, False)
End Function
Function UToD(Pt As Variant) As Variant
UToD = ThisDrawing.Utility.TranslateCoordinates(Pt, acUCS, acDisplayDCS, 0)
End Function
Function WToD(Pt As Variant) As Variant
WToD = ThisDrawing.Utility.TranslateCoordinates(Pt, acWorld, acDisplayDCS, 0)
End Function
-
The camera point is still eluding me. I've tried everything I can think of.
The camera pt ,view center and target are all on the line of sight, (so on viewdiection vector through the center.)
The camera point is a vector made by scaling the target along the view direction by the length from the target to the camera point.
This length from zero to the viewdir point is the length from target to the camera point, so we are good to go?
Nope viewdir doesn't update. Acad help:
VIEWDIR System Variable
Stores the viewing direction in the current viewport expressed in UCS coordinates.
This describes the camera point as a 3D offset from the target point
The camera length is related to the screensize, it changes with resolution, changing the size of the command line or the properties window. It changes with zoom but not pan. It is falsely updated with the view toolbar (Eg it will read 0,0,1 instead of 0,0,28) but does update with camera command or 3dorbit. Below gets close
Z = (dir(0) * (Wd + Ht) * 0.846553687811163) + Tar(0)
Dist = (Z - Cen(0)) / dir(0)
-
I've had a think on this and I think you will have to do some lower level mojo to get what you want.
I think what's happening is while the view direction is stored as a vector, it is one of the last transformations in the graphics pipeline before displaying to screen. That vector is passed to a matrix for the graphics to rotate the scene just before mapping to the viewport/client area, this means it will never be changed nor does it need to, it has the rotation set and is probably normalised before use. What does change though is the view size, this is actually the viewing volumes' front clipping plane mapped to the window/viewport, pan moves the model around in the viewing volume and zoom changes it's size (note the view width and heights in the view dlg after a zoom), all else outside the volume is clipped away. I had to do exactly this with a little app that I posted here -> http://www.theswamp.org/index.php?topic=13229.0
Now, given this info you would have to find out the view centre, draw a line along the view direction vector from there and find the intersection of this line and say the ucs plane to find the actual camera position in space. This means you can grab the new target and the view size, rotate the view vector and calc the new camera position...in theory anyway :)
Does that make sense?
I'll think on it more as I also need this to fine tune some viewing tools I'm working on, hope it helps.
-
Mick, the view center is on the ucs plane. I have viewctr and target worked out, I guess why I want the camera point is that it must hold the key to some weird number I need for a view matrix. I'm just not sure where to aim for. The view matrix I have made prints out the same as the cad view ucs one but doesn't quite work for angled views. Basically I'm trying to draw diagonal lines to show the screen dimensions and they end up with some weird offset that I cant figure out. I start by drawing the lines in modelspace using the viewctr, Screensize and viewsize to get widths and hts. Then use the matrix to transform the lines. I'ld post the code but I know you don't use vba.
-
On another note, that little app of yours is cool.
-
Perhaps someone will give this a go and get the ball rolling. Add it to a module and run the DrawViewDiagonals sub. Change the isoviews and run it, then 3d orbit views etc.