Is composing horz + vert shear the same thing as shearing both?
Bruce Pascoe

That topic title was probably confusing, so here's a better explanation: Allegro has these functions for doing shear transformation:

```al_horizontal_shear_transform()
al_vertical_shear_transform()
```

If I call both of these in sequence, is that the same thing as shearing both X and Y simultaneously? Think of CSS transformations, it has skewX/skewY() and then just skew() to do both at the same time.

I ask this because, in general, matrix multiplication is not commutative. For example translate + rotate is not the same thing as rotate + translate, and I wonder if the same caveat applies here.

SiegeLord

No, you do indeed get different effects depending on which way you skew first. To skew on both axes simulateously, you need a matrix that looks like this:

```1 x 0 0
y 1 0 0
0 0 1 0
0 0 0 1
```

Which Allegro doesn't have a simple function to create. I'd do this:

```ALLEGRO_TRANSFORM t;
al_identity_transform(&t);
t.m[1][0] = x;
t.m[0][1] = y;
al_compose_transform(&your_transform, &t);
```

Bruce Pascoe

Thanks, that's what I figured. On a related note, how would I figure out the shear factor given a skew angle? I think tan() is the right function here, but my trig is a bit rusty...

SiegeLord

Wikipedia suggests it's the cotangent, or 1/tan(angle).

Bruce Perry

Intuitively I expect it's tan if you're measuring the angle by which a horizontal or vertical line will change from its unskewed position; 1/tan if you're measuring the angle of the skewed line against the other axis.

Bruce Pascoe

@Bruce: I'm actually trying to figure out which values to plug into the matrix for a given skew angle--i.e. the angle is already known, and I need to calculate the shear factor from that. Allegro itself seems to use tan for this in al_*_shear_transform(), but like SiegeLord said Wikipedia calls to use the cotangent instead, so... yeah, I'm confused.

Bruce Perry

Hmm. I already knew what you were trying to do (you haven't told me anything new), and I was already trying to pre-empt and explain the exact confusion as to how it could be both tan and 1/tan. I assume Wikipedia is using the cotangent because their idea of an identity matrix would have an angle of 90°, whereas yours or Allegro's would have an angle of 0. (Of course remember to use radians in the implementation.)

(Possibly missing piece of the puzzle: tan(angle) = 1/tan(90° - angle).)

By the way, where is this on Wikipedia?

[EDIT]
I just found this:

Quote:

Straight lines parallel to the x-axis remain where they are, while all other lines are turned, by various angles, about the point where they cross the x-axis. Vertical lines, in particular, become oblique lines with slope 1/m. Therefore the shear factor m is the cotangent of the angle φ by which the vertical lines tilt, called the shear angle.

I think it's either unclear in its definition of the angle, or wrong. It absolutely has to be tan because tan(0) is 0 which leads to an identity matrix whereas 1/tan(0) is infinity (sort of). Who wants to fix Wikipedia?

Bruce Pascoe

Okay, I understand you now. I got confused because you said "measuring the angle", when in my case the angle is already known (and therefore doesn't need to be measured).

As for Wikipedia's definition, now that I read it again it actually seems to be correct, in a roundabout way. The article uses vertical lines as an example, but assumes the shear is along the X axis. In the case of perfectly vertical lines, the slope 1/m is either undefined or infinity, depending on how you want to interpret the division by zero. If they're measuring the angle of the oblique against the Y axis--in which case perfectly vertical lines are parallel, i.e. so that the slope is 1/Infinity = 0 (for our purposes anyway)--that might actually be correct. I say might because it's still very confusingly written, in any case--this is why Wikipedia is useless for any kind of mathematics research.

Trigonometry is fascinating!

edit + tl;dr: Wikipedia is measuring the oblique against the Y axis, not X. 1/tan is correct in that case.