Hi all,
When I try to read the area size of a curve it does not always match the expectation.
How to reproduce:
Create a Text with an "o" and set the size of it to 20 cm width (the height will be 22.263 cm). The box containing the "o" therefore equals 445,26 cm².
Convert the object to a curve, select it and run the macro:
Sub AreaTest() ActiveDocument.Unit = cdrCentimeter MsgBox ActiveSelection.Shapes(1).Curve.AreaEnd Sub
It will return 530.57. So how can the area of that "o" be bigger than the actual box around it? The "o" as a curve contains of 2 segments:
The "o" itself as a full block and its hallmark (is that the word used in english for that?). The returned value from above equals the area of both of these objects, however it should be the bigger minus the smaller value. This problem occurs with all objects that have hallmarks, all others work great.
Is this intended how it is? If so I find it very questionable that an area is returned that is just not correct from a visual point of view. I used another tool on the market to compare, and it does the job as I would expect
Can someone test this is the same in other versions of CorelDraw (I use 2021)? Is there a quick workaround maybe that I oversee?
Thanks for any help
Marian
Well, Corel treats such shapes in a peculiar way...
I mean, converting the 'O' letter to curve, Corel count the surface of both obtained curve (closed) lines. I mean, the internal elipse and the external one. In order to test that, try breaking apart the resulted shape and you will see that the resulted curves area sum is equal to the one returned by your code.
I do not want saying that this is a normal behavior. Only that you must take it as it is...
I will try preparing a piece of code, able to prove what I am trying to say...
Please, run the next code to exemplify what I tried explaining in words:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
Sub testShapeArea() Dim sh As Shape, sr As ShapeRange ActivePage.Shapes.All.Delete 'to allow playing with a newly created shape, without manually deleting it... Set sh = ActiveLayer.CreateArtisticText(0, 0, "O", , , "Arial") Application.Unit = cdrCentimeter ActiveDocument.Unit = cdrCentimeter sh.SetSize 20 sh.ConvertToCurves sh.CenterX = ActivePage.CenterX: sh.CenterY = ActivePage.CenterY Debug.Print "Curve area = " & sh.DisplayCurve.Area sh.BreakApart 'break the curve apart Set sr = ActiveSelectionRange 'create a shape range from the resulted shapes after break apart Debug.Print "First broken shape area = " & sr(1).DisplayCurve.Area Debug.Print "Second broken shape area = " & sr(2).DisplayCurve.Area Debug.Print "Total area of the broken shapes = " & _ sr(1).DisplayCurve.Area + sr(2).DisplayCurve.Area 'a workaround would be to decrease the small area from the bigger one, to obtain the real area you are interested in: Debug.Print "The O curve area is : " & Round(sr(1).DisplayCurve.Area - sr(2).DisplayCurve.Area, 2) & " cm2." End Sub
In this specific case, we could see that the bigger shape is the first in the broken apart range. I do not know if it will always will be the first, so I would recommend to firstly determine the broken curves area and decrease from the bigger one the smaller area.
Yes, I did similar testing. Sorry for not mentioning it. But thanks for your code, always nice to see how others approach a problem :)
I am just wondering if this really is intended since the result is just off of reality. I mean with letters it is very easy to fix, by looking at the subpaths of each letter and subtracting all smaller values from the biggest. But I am working with mostly complex geometries in for example logos and Corel completely fails those calculations.
So if there is no way for a quick workaround, maybe a better calculation is also not too difficult?
Lets assume we have complex geometries. First Get rid of all groups, Convert everything that is not a curve into a curve. Then get rid of all existing combinations (sometimes multiple letters are combined). Now ierate through all curves and combine thos who are in contact with other curves (e.g. the letter "g" with its 2 hallmarks). Now we should have all elements seperated from each other as a Curve. Finally get the biggest subpath of each curve and subtract all other subpath values from it.
Does this make sense?
In principle, yes, but I am not sure I get you completely...
For instance, in case of "g" (Arial) can be treated exactly like in the above code. It should be enough to count the resulted broken apart curves, determine which has the biggest area and subtract all smaller ones. I think that the first curve shape will always be the first. Not tested for everything, but I know that when you will brake apart a text converted to curve, the smaller curve shapes are behind the bigger one. Only trying to remember how things are going from this point of view. I remember that I needed to bring the smaller pieces in front and then trim the bigger one by them. I did not face such a situation and I never needed such a solution...
but I know that when you will brake apart a text converted to curve, the smaller curve shapes are behind the bigger one.
Yes, you are right. But thats what I meant by combining (Strg+L) those elements again that are in contact to each other. So that the "g" with its hallmarks becomes one curve with 3 subpaths. At least this way you don't have to bring anything to the front.
You can do it, but without any benefit, I am afraid...
I think the area of combined curve will be returned exactly like before braking it apart and recombining.