Rotation

Technical discussions
Post Reply
aarond
Posts: 8
Joined: Mon May 17, 2021 4:23 pm

Rotation

Post by aarond »

I am trying to figure out how to programmaticly get my model to rotate around the center of the model instead of around the global axis. For example when I use the mouse to drag the model around it spins along the center of the model, however using IView_DG.Rotate() or IFrame_DG.Rotate3() as in the rotation sample it rotates around the global axis instead of the center of the model. Reading the docs I feel like it has something to do with the ViewingVolume, but I can't work out how to use it to get the the behavior I want.

Alternatively, if there is a way to change the global origin to the center of the model that would work for me too.

nickz
Site Admin
Posts: 236
Joined: Fri Jul 26, 2013 3:58 am

Re: Rotation

Post by nickz »

It is a good question, Aaron

IView_DG.Rotate(double angle, double vx, double vy, double vz) is a shortcut, and not a very good one (our omission). It rotates around an axis passing through the current origin of eye frame, which stays the same as the global origin if you do not pan. We will look at changing it in the next version to use the center of the view volume. This is what the manual rotation with the mouse does.

For now you need to modify the eye frame:

Code: Select all

BoxDg vv = iView.GetViewingVolume();		// Ranges in eye frame
PointDg c = vv.GetPoint(new PointDg(0.5, 0.5, 0.5));						// Coordinates in eye frame

IFrame_DG frameEye = iView.GetEyeFrame();
frameEye.Rotate3(angle, c[0], c[1], c[2], vx, vy, vz);
Changing the global origin to the center of the model is doable as well. You could do it by translating all entities in your model by the same vector: IEntity_DG > GetLocation() > Translate(v). This is a modification of the model. So it is better to do it once and save.

v in the above can be found like:

Code: Select all

BoxDg bb = iModel.GetBoundingBox();
PointDg s = bb.GetPoint(new PointDg(0.5, 0.5, 0.5));	
VectDg v = new VectDg(-s[0], -s[1], -s[2]);
Regards

aarond
Posts: 8
Joined: Mon May 17, 2021 4:23 pm

Re: Rotation

Post by aarond »

Is this from the new .NET API? I like it, very clean. This didn't port directly to the current 6.2 API and for some reason the center of the depth of the viewing volume didn't quite match the model, so here is what I ended up with in C# case it helps someone else.

Code: Select all

private Point_DG GetCenterOfModel(IModel_DG model)
{
    Box_DG box = model.GetBoundingBox();
    IObjectGenerator_DG generator = model as IObjectGenerator_DG;
    IBox_DG boxDg = generator.Create("IBox_DG") as IBox_DG;
    boxDg.Init(box.range[0].min, box.range[0].max, box.range[1].min, box.range[1].max, box.range[2].min, box.range[2].max);
    Point_DG center = boxDg.GetCentre();

    return center;
}
And then to rotate around the Y axis:

Code: Select all

IModel_DG model = axKernCADnet.GetModel() as IModel_DG;
IView_DG view = axKernCADnet.GetView() as IView_DG;
IFrame_DG eyeFrame = view.GetEyeFrame();
Point_DG center = GetCenterOfModel(model);
eyeFrame.Rotate3(angle, center.x[0], center.x[1], center.x[2], 0, 1, 0);

nickz
Site Admin
Posts: 236
Joined: Fri Jul 26, 2013 3:58 am

Re: Rotation

Post by nickz »

Great that you have figured this out.

Sorry I got lazy with the snippet (corrected already). new BoxDg() is not needed and GetCenter() is only in v7.0.
BUT
This style is already available in v6.2. Search, say, for GetViewingVolume or GetBoundingBox in DGKernel_6_2\Samples\NET\C#\ and you will find debuggable examples.

Notice there is a new DGKernel_6_2\Samples\NET\C#\Shared\DT.cs which has the code for BoxDg, PointDg, etc. In the the above calls there is wrapping happening of the basic structures into the nice classes.

Similar to the samples, you can use the DT.cs as a link (for those who do not know: in Project > Add the Add button has an option "Add As Link") or copy the file into your project to modify it in any way.

For example, if you add to BoxDg

Code: Select all

public PointDg GetCenter() {return GetPoint(new PointDg(0.5, 0.5, 0.5)); }
what I wrote initially would be true :)

In v7.0 we have moved classes from DT.cs inside, so there is no need to mess with the file, and added lots more methods and new classes. You can still add staff using method extensions.

Post Reply