Could we please increase the number of digits in the reference matrices inside parts?

I was investigating very weird behavior of my part snapping code and it turns out it's caused by inexact rotation matrices derived from primitive references.

It concerned the 120 deg angles connecters (10288 and 57585)

Replacing the rotation matrix with

0.5 0.8660254037844 0 0 0 1 0.8660254037844 -0.5 0

fixed everything, so please don't spare those digits when referring stuff at angles.

Just venting

I totally agree that 4 or 5 digits is insufficient. But as a scientific programmer by trade, I reckon 13 digits is certainly pushing it the other way. Do all the LDraw codes even use double floats in their calculations?

Six is probably about right. Oddly enough I was thinking about this issue a couple of days ago.

Tim

LDView uses 32-bit floats, because those fit much better with high-speed OpenGL output.

Yes I might went a bit overboard there, but with the default resolution 10288 and 57585 just wouldn't snap together aligned over their axles.

For example I don't think the attached ldr would be possible with less then e.g. 6 digits (in parts).

ps: Please ignore the many digits in the ldr it self, for models 4 would be fine, i just enabled more digits in my debug build so I can copy paste the matrices.

It depends what you mean by 'snap' I guess. One silly thing we do with LDraw parts is zoom in to the parts so much that in reality you would need a microscope!!! Real tolerance on bricks is, according to legend, about 1/16 LDU so anything beyond that is pure nerd games

The longest part I know of is 55 studs long (a flex tube) or 1100LDU long. The maximum error of a rotation with 4 decimal places is 5/1000 meaning that such a rotation would give an error of about 5LDU (which is bad). Taking it to 6 decimal places gives 1/20 LDU, which is less than the tolerance in LEGO.

Ramble, ramble, ramble

Tim

Apparently it all gets really complicated when you consider that GPUs often do their arithmetic in different byte floats to the CPU. Apparently this causes real problems for scientists who use GPUs to speed up calculations. Not being on of those scientists I don't know the details.

Tim

My part snapping code tries to pull parts together. So when you want to insert a part and it connects to something in the scene it pulls the to be inserted one so the target's y-axis' so they align.

For the three way connector parts 10288 and 57585 this goes visually wrong for some axles because both have rounding errors so even over 20LDU they end up about 1 deg crooked.

I use double precision for all matrix math in LDCad, vectors to be send to OpenGL are float but any in between (pre processing) math uses double vectors when appropriate.

Gotcha.

I guess with more sig-figs you'd end up with less problem. But it's still going to bite eventually. Would be nice to use mathematical definitions e.g. cosd(60) and sind(60)... but that is dream land

I'm guessing your connections are often based on the position of only a limited selection of primitives that are defined to be unscalable. If so, you might try rounding the normalised matrix elements (at read time for the part) to the cosine of the nearest 7.5 degree angle (which covers both 22.5 and 30) when the error that would give is smaller than a tolerance.

e.g.

acosd( 0.86603 ) = 29.999

therefore round to 30 (error < 1 degree) and replace by cosd(30) = 0.866025404...

acosd( 0.81 ) = 35.904

leave as is (err > 1 degree)

Perhaps...

A while back I was thinking something similar, a lookup table to convert the rounded '.nnnn' strings from type 1 lines to true sin/cos values for the common values (0.707 etc) but your idea is faster and more global.

To be able to place sin(45) right in the type 1 line would be the best solution indeed, but it will indeed never happen. I might add it to my own snap meta's though.