# Forums

The forums ran from 2008-2020 and are now closed and viewable here as an archive.

Home Forums CSS Why is rotated pentagon placed inaccurately?

• This topic is empty.
Viewing 9 posts - 1 through 9 (of 9 total)
• Author
Posts
• #283982
Shikkediel
Participant

Just fiddling aorund, trying to make a three-dimensional dodecahedron. The `clip-path` coordinates to create a pentagon are calculated up to two decimals and the angle of the right top side is 36 degrees exactly (down from an imaginary line at the top, corresponding with a `rotateZ` of the element)…

But when it try to translate and rotate a second element to fit that side, the outcome isn’t accurate – neither in FF nor Chrome. It seems a 37 degree rotation is closer to what is to be expected.

Anybody has an idea as to why?

codepen.io/anon/pen/bZpWga

You don’t actually see the second decimal in the `polygon` value because they are all zero when rounded by the way.

#283983
Shikkediel
Participant

Still curious for an explanation… but it seems that instead of using a translation and partial rotation to match the side, making the center of the side in question the rotation point and rotating the entire element by 180 degrees gives a more accurate result. I think I’ll go with that for all surrounding elements, the left and right ones on the bottom were a little bit off too (still shown in the demo below).

codepen.io/anon/pen/jJqwGN

#283997
Shikkediel
Participant

That got complicated quickly as well. It needed a third level nested transform that wasn’t even that accurate either. So time for a complete rethink – new approach, rotate each element around the center of the circumscribed circle first (apart from the bottom one) by a multide of 72 degrees and then basically flip them all over by the bottom. This requires two levels of transforms and involves only rotation (which appears to be more accurate than including translations).

https://codepen.io/Shikkediel/pen/bZVKXy

Quite happy now.

#284020
Shikkediel
Participant

Opening up the demos in the first two posts and switching between them, I noticed the top pentagons in the first one actually look somewhat deformed. I doubt it’s supposed to be like that…

Makes me think it’s not an incorrect rotation angle – but rather that the pentagon is “stretched out” when using both translations and rotation.

#284101
Shikkediel
Participant

Yay, rounded corners. Achieved by a double (nested) `clip-path`. Gotta love it, support is pretty good these days too. The rounding is subtle in the pen but very noticeable when it’s not there.

Just wanted to add that, not very on-topic.

As to the original question, I suppose using percentages for the `polygon` and rounding effects are the cause. I doubt an image would get twisted like that.

#284307
Shikkediel
Participant

Instead of reposting the topic that went to spam, I’ll post my findings here because it might be interesting to someone looking for the same answer when searching the web. There is good information on 3D transforms but most of it doesn’t go very deep into the matrices themselves. So here it goes.

Intro – rotating elements 3D works fine when `backface-visibility` is set to `hidden` because those elements that are facing to the back will not be noticeable. But when the property is set to `visible` the element that comes last in the stacking order is always on top, showing the backside of elements above those are actually facing forward. Here is an example:

codepen.io/anon/pen/MxpzbO

When reactivacting the style for `.face &gt; div` that is commented out, the shape’s appearance becomes solid. The backwards flipped elements are no longer visibly on top (physically they still are).

Because I’d like to make a transparent version of that demo, a mechanism is needed to show the elements on top that are actually facing forward. Unfortunately this is only possible with Javascript and it is quite the tour. Three levels of nested elements have transforms on them so these needed to be combined. In the CSS the matrices are only given for the individual elements, not the total transform including the influence of additional transforms on parents. I have gotten that far, by “analysing” and multiplying the separate values of `matrix()` and `matrix3d()` from the CSS. So what I have now is a final matrix for each element of the shape. This demo shows the values for one of them (the rest have been made transparent):

codepen.io/anon/pen/BbWGrQ

Click on the element to clear the text field…

My question in the other topic I posted was how to make sense of a matrix value (that contains three directional vectors) like this – and determine what calculation would be needed to figure out if the element is facing forward:

`matrix3d(-1,0,0,0,0,-0.276,0.961,0,0,0.961,0.276,0,0,0,0,1)`

Written as a “real” matrix as such:

``````-1     0          0     0
0  -0.276  0.961   0
0   0.961  0.276   0
0     0          0     1
``````

That last step to figure out what defines the direction it’s facing turned out to be quite simple – if the third value in the third column is positive, it’s facing forward. Negative means it’s flipped. Knowing this, I’ve been able to make the above demo look semi-transparent. Neat.

#284308
Shikkediel
Participant

That matrix is a mess, no clue how to line that up here…

The two zeros on the right middle clearly belong in the last column. The ones slightly above and below to the left of them are in the third column.

By the way, I thought it would be easy to just set a negative z-index when the element is flipped but that of course doesn’t work with 3D transforms. So the solution I chose for that was to have alternates to the elements that are on top. These are placed in the HTML before everything else (so lower in the stacking order) and not displayed. When a surface flips, it is hidden and this alternate is shown instead.

#284813
Shikkediel
Participant

After a re-rethink (leading to a redesign), I realised that the facets can be placed using a single transform when using the radius of the inscribed sphere as the transform origin. Now instead of three levels, only two need to be calculated. Even if it wasn’t heavily scripted, this is still a nice optimisation.

Also used a bunch of transformed pseudos to create a `box-shadow` around the polygon… it neatly hides the minor transform inaccuracies that occur where the edges meet.

It’s (potentially) responsive by the way, everything adapts to the size of `.inner`.

#284837
Shikkediel
Participant

One last tip, should anyone happen to land on this topic – don’t use `display: none` to toggle between elements on the front and the back because Chrome then removes their transform (making the total incalculable). Better to use `visibility: hidden` instead.

Viewing 9 posts - 1 through 9 (of 9 total)
• The forum ‘CSS’ is closed to new topics and replies.