Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

skew() function in depth

I really need to understand how skew(xdeg) function works all research does not seem to explain how the x angle affecting the other points and distorts it like that, I need to know if there any mathematical formula it or a way to be able to expect the result of using a specific degree.

ps. I already read tons of docs which the best one of them was the DevDocs which say

This transformation is a shear mapping (transvection) that distorts each point within an element by a certain angle in the horizontal and vertical directions. The coordinates of each point are modified by a value proportionate to the specified angle and the distance to the origin; thus, the farther from the origin a point is, the greater will be the value added it.

but there is no further explanation for how the given angle will affect those points in an element.

In SVG book it explains skew by saying it pushes a horizontal or a vertical line by specific value but I don't get how deg value is translated to offset one

like image 265
A. AbdElaal Avatar asked Aug 30 '18 01:08

A. AbdElaal


People also ask

What is the function of the skew feature?

Description. Returns the skewness of a distribution. Skewness characterizes the degree of asymmetry of a distribution around its mean. Positive skewness indicates a distribution with an asymmetric tail extending toward more positive values.

What does the skew value tell us?

In statistics, skewness is a measure of the asymmetry of the probability distribution of a random variable about its mean. In other words, skewness tells you the amount and direction of skew (departure from horizontal symmetry). The skewness value can be positive or negative, or even undefined.

How does the skew function work in Excel?

SKEW is a function in Excel that calculates the standard deviation of the logarithms of the individual values in a data set. It is most often used to measure the asymmetry of a distribution. The SKEW function can be used in conjunction with the Excel AVERAGE function to calculate the value of the skewness coefficient.


2 Answers

The mathematical operation that is applied on the <angle> is simply tan(<angle>). It is then inserted in the transformation Matrix.

Ok, that doesn't really goes in depth about skew, nor why it makes sense to use angle rather than a numeric factor. So let's take the following ASCII example showing an x only skew.

   skewX(0)            skewX(45deg)
_|         |_         _|         |_ => original box markers
  a o o o o         a o o o o    
  b o o o o           b o o o o
  c o x o o             c o x o o   <-- this line didn't move
  d o o o o               d o o o o
  e o o o z                 e o o o z
 |         |           |         |

So if we apply the tan(45deg) it gives us a skewX factor of 1.
This means that all the horizontal lines will get displaced by 1 * their distance to the transformation origin.

In above example the transformation origin is the center (x) of the 5*5 image.
So the first pixel line (a o o o o) being at a distance of minus two pixels from the origin, it will get translated by 2px on the left.
The last line (e o o o z) being at +2px from the origin, it will get translated by 2px on the right.
The middle line (c o x o o) being on the origin will not be affected by this transform.

Alright, but that still doesn't explain why bother with angles rather than a factor...

Well the angle notation makes sense too, since we could also explain our example as we rotated every column by 45deg using their center point as anchor.

And even if it is just speculations from my part, angles have the added benefit to allow a skewN(90deg) state which couldn't be represented by a numeric factor.

like image 117
Kaiido Avatar answered Oct 19 '22 22:10

Kaiido


To understand how skew works let's compare it with another transformation that uses angle.

Here is an example with rotation, we make the transform origin to be top left and from there we rotate by 45deg:

.box {
  margin:50px;
  width:200px;
  height:200px;
  background:blue;
}
.box > div {
  height:100%;
  width:100%;
  background:rgba(255,0,0,0.5);
  transform-origin:top left;
  transform:rotate(45deg);
}
<div class="box">
  <div></div>
</div>

For this example, it's somehow trivial to find the angle and how it works:

enter image description here

Now let's take the same example and reduce the height of the rotated element to a small value:

.box {
  margin:50px;
  width:200px;
  height:200px;
  background:blue;
}
.box > div {
  height:3px;
  width:100%;
  background:red;
  transform-origin:top left;
  transform:rotate(45deg);
}
<div class="box">
  <div></div>
</div>

It's like we have a rotated line. Now let's replace rotate with skew:

.box {
  margin:50px;
  width:200px;
  height:200px;
  background:blue;
}
.box > div {
  height:3px;
  width:100%;
  background:red;
  transform-origin:top left;
  transform:skewY(45deg);
}
<div class="box">
  <div></div>
</div>

If we compare both result we will notice that we have somehow a rotation in both cases BUT a different size when it comes to skew transformation:

enter image description here

It's more clear now how skew works with angle. The transform is a kind of distortion that rely on an angle to define this distortion. Here is a better illustration:

enter image description here

The blue is our initial element, the cross is the transform origin and the yellow is the angle. If we do a rotation we will obtain the red line where the width remain the same. If we do a skew we will obtain the orange line where the width will change and considering the illustration it will be equal to W / cos(angle) Where W is our initial width (in our previous case cos(45deg) = 1 / sqrt(2) so we will have W * sqrt(2)).


Now what about our intial square, how it will behave with skew?

.box {
  margin:50px;
  width:200px;
  height:200px;
  background:blue;
}
.box > div {
  height:100%;
  width:100%;
  background:red;
  transform-origin:top left;
  transform:skewY(45deg);
}
<div class="box">
  <div></div>
</div>

It will behave exactly like we described previously line by line. We will also have the same result if we apply skew in the other direction:

.box {
  margin:50px;
  width:200px;
  height:200px;
  background:blue;
}
.box > div {
  height:100%;
  width:100%;
  background:red;
  transform-origin:top left;
  transform:skewX(45deg);
}
<div class="box">
  <div></div>
</div>

The same logic is applied but to vertical lines and considering the height. As a side note, skewX(V) is the same as skew(V)ref.

Now if we apply skew in both direction:

.box {
  margin:50px;
  width:200px;
  height:200px;
  background:blue;
}
.box > div {
  height:100%;
  width:100%;
  background:red;
  transform-origin:top left;
  transform:skew(45deg,10deg);
}
<div class="box">
  <div></div>
</div>

It's like we first apply skewX to distort the vertical lines then we apply skewY to the new shape to distort the horizontal lines (or the opposite). Here is an animation to illustrate the magic result of skew(45deg,45deg):

.box {
  margin:50px;
  width:200px;
  height:200px;
  background:blue;
}
.box > div {
  height:100%;
  width:100%;
  background:red;
  transform-origin:top left;
  transform:skew(45deg,10deg);
  animation:change 5s infinite alternate linear;
}
@keyframes change {
  from {
    transform:skew(0deg,0deg);
  }
  50% {
    transform:skew(45deg,0deg);
  }
  to {
    transform:skew(45deg,45deg);
  }
}
<div class="box">
  <div></div>
</div>

And what about origin? Nothing will change for the transformation, only the reference will change. In other words, the fixed point will move:

.box {
  margin:50px;
  width:200px;
  height:200px;
  background:blue;
}
.box > div {
  height:100%;
  width:100%;
  background:red;
  transform-origin:center;
  transform:skew(45deg,10deg);
  animation:change 5s infinite alternate linear;
}
@keyframes change {
  from {
    transform:skew(0deg,0deg);
  }
  50% {
    transform:skew(45deg,0deg);
  }
  to {
    transform:skew(45deg,45deg);
  }
}
<div class="box">
  <div></div>
</div>

We may also notice that if we do skew in one direction only one parameter of transform-origin will be considered.

So for skewX, transform-origin: X Y will be the same whataver the value of X is. This somehow explain the line by line transformation as when we have on line we have one dimension.

.box {
  margin:50px;
  width:200px;
  height:200px;
  background:blue;
}
.box > div {
  height:100%;
  width:100%;
  background:red;
  transform:skewX(45deg);
  animation:change 5s infinite alternate linear;
}
@keyframes change {
  from {
    transform-origin:0 0;
  }
  50% {
    transform-origin:100% 0;/*nothing will happen between 0 and 50%*/
  }
  to {
    transform-origin:100% 100%;
  }
}
<div class="box">
  <div></div>
</div>

More in depth

Now let's consider the matrix calculation to understand how it's used and how tan(angle) is also used.

If we refer to the documentation we have:

enter image description here

This matrix is used to define the coordinates of the transformed element based on the coordinate of the initial element point by point. Considering this definition we will have these equations

Xf = Xi + Yi * tan(ax)
Yf = Xi * tan(ay) + Yi

If we consider skewY only it's clear that ax will be 0 thus tan(0) will be 0 and X won't change which is the case with our first example where we only had distortion in the Y axis (same logic if we apply only skewY).

Now, why we have Yf = Xi * tan(ay) + Yi?

Let's re-take the previous illustration:

enter image description here

The green point is the initial point defined by Xi,Yi and the red point is the tranformed one defined by Xf,Yf. It's trivial that Xf=Xi and the distance between the two points will be Yf-Yi.

Considering the illustration we can clearly say that tan(ay) = (Yf-Yi)/Xi = (Yf-Yi)/Xf thus we will have:

Xf = Xi 
Yf = Xi * tan(ay) + Yi

We apply the same logic if we have skew in the other direction.

like image 38
Temani Afif Avatar answered Oct 19 '22 20:10

Temani Afif