Closed iborzenkov closed 3 years ago
Your issue is the typical rounding error when working with sines and cosines. A similar issue as yours may affect transformations of attribute definitions and texts. If you need a quick fix for it go to the MathHelper.NormalizeAngle and where is says:
if (IsZero(normalized))
write
if (IsZero(normalized) || IsEqual(Math.Abs(normalized), 360.0))
As a side note, I've seen in your example you are calling the Sync() method of the Insert where the TransformAttributes() method is all you need. While the Sync() will also modify the attributes properties to accommodate the transformation state of the insertion, it will also add and delete attributes in the list to synchronize it to the attribute definitions list defined in the block. The TransformAttributes() only transform them, making changes to the insert position, rotation, normal, and/or scale; when changing the block origin and/or units; or even the document insertion units will require this method to be called manually. In your case you are only modifying the insert rotation property therefore a call to TransformAttributes() is all you need.
I have a block placed in a DXF file. I load it into my program using NetDXF, visualize it in some way, also I initialize some of the block attributes. Then I upload it back to DXF, again using NetDXF. In fact, I perform actions in my program similar to the usual block insertion in AutoCAD. However, the result is different.
I brought them in the picture
On the left is a block inserted using AutoCAD, on the right is a block inserted using NetDXF. I will pay attention to the block attributes, the
ObliqueAngle
,WidthFactor
andHeight
parameters are incorrect.To make it easier to reproduce the error, debug and fix the problem, I created an unit test. The original DXF file that is mentioned in the unit test can be found here.
I see problems in the
Attribute.TransformBy(Matrix3 transformation, Vector3 translation);
method.I solved my problems by adding the logic of rounding instead
newObliqueAngle = 90 + (newRotation - newObliqueAngle);
I usingnewObliqueAngle = Math.Round(90 + (newRotation - newObliqueAngle), 0, MidpointRounding.AwayFromZero);
for my tasks, angles accurate to whole degrees are enough. But this solution may not be suitable for other users.