Re: Calculating accurate bounds of stroked paths
Re: Calculating accurate bounds of stroked paths
- Subject: Re: Calculating accurate bounds of stroked paths
- From: Peter Zegelin <email@hidden>
- Date: Wed, 9 Jul 2008 16:22:11 +1000
Ok - one last time!!
I believe the fully correct answer to calculate the extension is:
(strokeWidth/2)/ sin(angle/2);
Take a stroke width of 20 half of which is 10.
At 90deg the extension is: 10/sin(45) = 14.2
At 45deg the extension is 10/sin(22.5) = 26.1
At the limit of approx. 11deg the extension is 10/sin(5.5) = 104.
( which is close to the 10x mentioned in the docs)
These figures closely match what I have observed by 'sight'. Note that
at 0 degrees the extension becomes infinite and you will get a divide
by zero.
Whew! I hope I haven't confused you even more!
Peter
On 09/07/2008, at 3:40 PM, Peter Zegelin wrote:
Actually Graham I think I got it a bit wrong. I was working by
induction and it just happened that the two data points more or less
worked. My picture at 45 deg wasn't actually 45 deg (I did it on
sight). However I believe the correct value uses the sin. eg
sin(11.5deg) = .199, sin(45) = .707 and sin(90) = 1. Therefore at
11.5deg the extension is 5x, at 45deg it is 1.414x and at 90 it is
1x (which is what you would expect). I redid my 45deg picture and I
do indeed get an extension of ~1.41x
Sorry for confusion.
hth,
peter
On 09/07/2008, at 2:56 PM, Peter Zegelin wrote:
Graham,
Since no-one else has replied and I'm going to have to figure out
this myself, I thought I'd take a stab at it. I've uploaded some
screen shots http://www.fracturedsoftware.com/downloads/
Stroke20.tiff and http://www.fracturedsoftware.com/downloads/Stroke30.tiff
of a simple poly line with an angle set just about at the minimum
before the join converts to a bevel (presumably ~11 deg). In the
stroke20 pic the maximum extension is almost exactly 100 pixels and
in the stroke30 it is 150 pixels. I tried with a 10 pixel stroke
and got 50 pixels for the extension. It would seem that the
relationship would be 10 times half the stroke width at the maximum
(or 5 times)
I then created another simple polyline at about 45deg http://www.fracturedsoftware.com/downloads/Stroke20-45.tiff
. The extension was also 20. Now tan45deg is 1. So we have a stoke
of 20 and an extension of 20 at 45deg. So extension = strokewidth /
tan(angle) maybe. Interestingly, going back to the first example
tan(11deg) is .194. Put that into the equation and you get
20/.194 = ~ 100. The docs say approx 11deg for the max - its closer
to 11.2 by this calculation.
I know this is a fair way from a suitable algorithm but maybe a
start and I sincerely hope I haven't lead you up a completely wrong
path!
hth,
Peter
On 08/07/2008, at 11:24 PM, Kai wrote:
Hi,
have you checked CGContextReplacePathWithStrokedPath (CGContextRef
c) ? This together with CGRect CGContextGetPathBoundingBox
(CGContextRef c) might do the trick for you.
Best,
Kai
On 8.7.2008, at 14:16, Graham Cox wrote:
I need to know a rect within which all pixels will be painted for
a given path and stroke width. I'd prefer not to make this rect
any larger than it really needs to be. To compute this, I have to
factor in all sorts of bits and pieces such as the angles of the
line joins, miter limits and so on. It's getting so complicated I
feel there has to be an easier way. Surely there's something in
Quartz that can do this?
A close second best would be a rect that was the worst case
bounds for a given stroke width (it wouldn't need to know the
actual path, just its basic bounds), which thus assumed that all
angles were acute enough to trigger the mitre conversion. Even
that is proving hard to figure, as I'm probably not really
understand the miter limit calculation. The docs state:
"The miter limit helps you avoid spikes at the junction of two
line segments connected by a miter join (NSMiterLineJoinStyle).
If the ratio of the miter length—the diagonal length of the miter
join—to the line thickness exceeds the miter limit, the joint is
converted to a bevel join. The default miter limit value is 10,
which converts miters whose angle at the joint is less than 11
degrees."
So what *is it*? A value in degrees? Or a ratio of two sides of a
triangle? What triangle, exactly? How can I tell just how far out
I need to outset the rect to make sure I'm always just outside
the edge of any mitred corner?
thanks for any insight into this, it's getting frustrating. I'm
pretty OK at trig generally, but the definition is a bit vague,
so I'm not sure what I should be using as my starting points (I
possibly mean that literally!).
cheers, Graham_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the
list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden