-1

I want to rotate my object,when I use glm::rotate.

It can only rotate on X,Y,Z arrows.

For example,Model = vec3(5,0,0)

if i use Model = glm::rotate(Model,glm::radians(180),glm::vec3(0, 1, 0));

it become vec3(-5,0,0)

i want a API,so i can rotate on vec3(0,4,0) 180 degree,so the Model move to vec3(3,0,0)

Any API can I use?

genpfault
  • 51,148
  • 11
  • 85
  • 139
Kevin Su
  • 542
  • 2
  • 6
  • 24
  • @Spektre Can you clarify on *"in OpenGL you use glRotate which is quaternion"*? It thought it uses a rotation matrix, no? – HolyBlackCat May 04 '18 at 06:35
  • yes,i want a rotation matrix to rotate my object.(4,5,0) is vector – Kevin Su May 04 '18 at 06:37
  • I give a example,i think you will know what i mean. if a point on (5,0,0) i use glm::rotate (0,1,0) it will become (-5,0,0).i wnat a API to rotate on (4,0,0) so the point become (3,0,0) – Kevin Su May 04 '18 at 06:43
  • @kevinsu: "*i wnat a API to rotate on (4,0,0) so the point become (3,0,0)*". But... that's not a *rotation*. You can tell because the two vectors have the same direction. – Nicol Bolas May 04 '18 at 13:48
  • @Nicol Bolas Why that's not a rotation? (4,0,0)is a vector,where i rotate 180 degree on it.My point(5,0,0)->(3,0,0).i thing you was misunderstanding. – Kevin Su May 04 '18 at 14:48
  • @HolyBlackCat My bad it is not quaternion (even if internally might be used to compute that, as Nico Bolas correctly pointed out) I should wrote `glRotate` have 4 input parameters not just 3 .... and it rotates around vector instead of just around base axises (axis aligned incremental rotation) – Spektre May 04 '18 at 16:50

1 Answers1

4

Yes OpenGL uses 4x4 uniform transform matrices internally. But the glRotate API uses 4 parameters instead of 3:

glMatrixMode(GL_MODELVIEW);
glRotatef(angle,x,y,z);

it will rotate selected matrix around point (0,0,0) and axis [(0,0,0),(x,y,z)] by angle angle [deg]. If you need to rotate around specific point (x0,y0,z0) then you should also translate:

glMatrixMode(GL_MODELVIEW);
glTranslatef(+x0,+y0,+z0);
glRotatef(angle,x,y,z);
glTranslatef(-x0,-y0,-z0);

This is old API however and while using modern GL you need to do the matrix stuff on your own (for example by using GLM) as there is no matrix stack anymore. GLM should have the same functionality as glRotate just find the function which mimics it (looks like glm::rotate is more or less the same). If not you can still do it on your own using Rodrigues rotation formula.

Now your examples make no sense to me:

(5,0,0) -> glm::rotate (0,1,0) -> (-5,0,0)

implies rotation around y axis by 180 degrees? well I can see the axis but I see no angle anywhere. The second (your desired API) is even more questionable:

 (4,0,0) -> wanted API -> (3,0,0) 

vectors should have the same magnitude after rotation which is clearly not the case (unless you want to rotate around some point other than (0,0,0) which is also nowhere mentioned. Also after rotation usually you leak some of the magnitude to other axises your y,z are all zero that is true only in special cases (while rotation by multiples of 90 deg).

So clearly you forgot to mention vital info or do not know how rotation works.

Now what you mean by you want to rotate on X,Y,Z arrows? Want incremental rotations on key hits ? or have a GUI like arrows rendered in your scene and want to select them and rotate if they are drag?

[Edit1] new example

I want a API so I can rotate vec3(0,4,0) by 180 deg and result will be vec3(3,0,0)

This is doable only if you are talking about points not vectors. So you need center of rotation and axis of rotation and angle.

// knowns
vec3 p0 = vec3(0,4,0);  // original point
vec3 p1 = vec3(3,0,0);  // wanted point
float angle = 180.0*(M_PI/180.0); // deg->rad
// needed for rotation
vec3 center = 0.5*(p0+p1); // vec3(1.5,2.0,0.0) mid point due to angle = 180 deg
vec3 axis = cross((p1-p0),vec3(0,0,1)); // any perpendicular vector to `p1-p0` if `p1-p0` is parallel to (0,0,1) then use `(0,1,0)` instead
// construct transform matrix
mat4 m =GLM::identity(); // unit matrix
m = GLM::translate(m,+center);
m = GLM::rotate(m,angle,axis);
m = GLM::translate(m,-center); // here m should be your rotation matrix
// use transform matrix
p1 = m*p0; // and finaly how to rotate any point p0 into p1 ... in OpenGL notation

I do not code in GLM so there might be some little differencies.

Spektre
  • 49,595
  • 11
  • 110
  • 380
  • thanks your reply. I edit my question,hope you know what i mean,if not,I would give more info to you – Kevin Su May 04 '18 at 09:42
  • @kevinsu api is the same you just need to compute the stuff you need for rotation that is pure math see edit1 also I repaired the translation signs (where inverted) – Spektre May 04 '18 at 10:47
  • Actually I used your method before.but it can't work.because when you translate or rotate in 3D view,it will rotate or translate camera. – Kevin Su May 04 '18 at 10:50
  • @kevinsu why? you rotate translate the camera only if you use camera matrix ... if you use this on MODELVIEW matrix then you need to apply this in the right place of code where the transform order will stack up to your model instead of the camera easier is to have 2 separate matrices internally like [Camera Frame and Object Frame](https://stackoverflow.com/a/49841796/2521214) and use the multiplied for rendering but for internal computations like this use your separate matrices .... see the last 3 links in the 4x4 uniform matrix link there are examples of this ... – Spektre May 04 '18 at 10:53
  • God,I know how to do.thanks a lot.i will give you accept. – Kevin Su May 04 '18 at 11:12
  • @HolyBlackCat not in GL however in GLM I do not know depends on the notation too if you use inverse matrices instead then yes – Spektre May 04 '18 at 20:15
  • @Spektre Huh. I tried it and indeed you're correct. – HolyBlackCat May 04 '18 at 20:34