Setting up your ViewOrientation3D
Originally Published inHere is a contribution from Mario Guttman of CASE ↗, who already made various contributions here in the past. He says:
I have been purging my 2013 code of deprecated functions in preparation for my 2014 upgrade. One group of statements I have needed to replace are the view creations. They were previously using the Document.Create.NewView3D method and needed converting to the View3D.CreateIsometric with a separate ViewOrientation3D object defining the view direction.
Typically, in these kind of cases, I just search your blog for the answer. In this case I found a few references, for example your March 04, 2013 item on What’s New in the Revit 2013 API – View API – View Creation. This, together with the wikihelp entry on the View3D class ↗, describe the new syntax, but they don’t really explain how you would create the values.
After searching the inner reaches of my brain for some ancient math skills I figured out the following:
Assuming that your user interface has produced two angular values (in degrees):
/// <summary>
/// The angle in the XY plane (azimuth),
/// typically 0 to 360.
/// </summary>
double angleHorizD;
/// <summary>
/// The vertical tilt (altitude),
/// typically -90 to 90.
/// </summary>
double angleVertD;
Then this utility function returns a unit vector in the specified direction:
/// <summary>
/// Return a unit vector in the specified direction.
/// </summary>
/// <param name="angleHorizD">Angle in XY plane
/// in degrees</param>
/// <param name="angleVertD">Vertical tilt between
/// -90 and +90 degrees</param>
/// <returns>Unit vector in the specified
/// direction.</returns>
private XYZ VectorFromHorizVertAngles(
double angleHorizD,
double angleVertD )
{
// Convert degreess to radians.
double degToRadian = Math.PI * 2 / 360;
double angleHorizR = angleHorizD * degToRadian;
double angleVertR = angleVertD * degToRadian;
// Return unit vector in 3D
double a = Math.Cos( angleVertR );
double b = Math.Cos( angleHorizR );
double c = Math.Sin( angleHorizR );
double d = Math.Sin( angleVertR );
return new XYZ( a * b, a * c, d );
}
From this it is easy to create the ViewOrientation3D object as follows:
XYZ eye = XYZ.Zero;
XYZ forward = VectorFromHorizVertAngles(
angleHorizD, angleVertD );
XYZ up = VectorFromHorizVertAngles(
angleHorizD, angleVertD + 90 );
ViewOrientation3D viewOrientation3D
= new ViewOrientation3D( eye, up, forward );
Although it is already explained in one of your other posts, just for completeness, here is the final step is to apply the orientation to the view:
ViewFamilyType viewFamilyType3D
= new FilteredElementCollector( doc )
.OfClass( typeof( ViewFamilyType ) )
.Cast<ViewFamilyType>()
.FirstOrDefault<ViewFamilyType>(
x => ViewFamily.ThreeDimensional
== x.ViewFamily );
View3D view3d = View3D.CreateIsometric(
doc, viewFamilyType3D.Id );
view3d.SetOrientation( viewOrientation3D );
I hope you find this useful.
Personally, I do indeed.
Many thanks to Mario for sharing!
Addendum
Colmag adds in his comment below:
Thank you for sharing this info, it’s made life a whole lot easier in setting 3D view orientation.
It did take me a short while to work out the values to replicate top and bottom isometric views from each corner of the view cube, so I thought I’d share the values here for others. Looking at them listed out they are pretty obvious, but faced with a blank sheet things didn’t seem so straight forward!
-
Horizontal Angles:
-
Left Front = 45
-
Front Right = 135
-
Right Back = 225
-
Back Left = 310
-
Vertical Angles:
-
-30 = Top
-
30 = Bottom
Many thanks to Colmag for this useful addition!
Addendum 2
K C Tang added a further simplification in his comment below:
I found that the formula above using ( a * b, a * c, d )
to calculate the return value from VectorFromHorizVertAngles
can be further simplified, because:
( a * b, a * c, d )
≡ ( a * b / a , a * c / a, d / a )
= (b, c, d/a)
= (b, c, e),
where
double e = Math.Tan( angleVertR ).
In words, the return value from VectorFromHorizVertAngles
can be defined as:
- cos (horizontal angle) for X
- sin (horizontal angle) for Y
- tan (vertical angle) for Z
Many thanks to K C Tang for this simplification and explanation highlighting the basic trigonometric relationships between the angles and the vectors involved so much better than the original version!