MCPcopy
hub / github.com/tdewolff/canvas / flattenEllipticArc

Function flattenEllipticArc

path_util.go:345–385  ·  view source on GitHub ↗
(start Point, rx, ry, phi float64, large, sweep bool, end Point, tolerance float64)

Source from the content-addressed store, hash-verified

343}
344
345func flattenEllipticArc(start Point, rx, ry, phi float64, large, sweep bool, end Point, tolerance float64) *Path {
346 if Equal(rx, ry) {
347 // circle
348 r := rx
349 cx, cy, theta0, theta1 := ellipseToCenter(start.X, start.Y, rx, ry, phi, large, sweep, end.X, end.Y)
350 theta0 += phi
351 theta1 += phi
352
353 // draw line segments from arc+tolerance to arc+tolerance, touching arc-tolerance in between
354 // we start and end at the arc itself
355 dtheta := math.Abs(theta1 - theta0)
356 thetaEnd := math.Acos((r - tolerance) / r) // half angle of first/last segment
357 thetaMid := math.Acos((r - tolerance) / (r + tolerance)) // half angle of middle segments
358 n := math.Ceil((dtheta - thetaEnd*2.0) / (thetaMid * 2.0))
359
360 // evenly space out points along arc
361 ratio := dtheta / (thetaEnd*2.0 + thetaMid*2.0*n)
362 thetaEnd *= ratio
363 thetaMid *= ratio
364
365 // adjust distance from arc to lower total deviation area, add points on the outer circle
366 // of the tolerance since the middle of the line segment touches the inner circle and thus
367 // even out. Ratio < 1 is when the line segments are shorter (and thus not touch the inner
368 // tolerance circle).
369 r += ratio * tolerance
370
371 p := &Path{}
372 p.MoveTo(start.X, start.Y)
373 theta := thetaEnd + thetaMid
374 for i := 0; i < int(n); i++ {
375 t := theta0 + math.Copysign(theta, theta1-theta0)
376 pos := PolarPoint(t, r).Add(Point{cx, cy})
377 p.LineTo(pos.X, pos.Y)
378 theta += 2.0 * thetaMid
379 }
380 p.LineTo(end.X, end.Y)
381 return p
382 }
383 // TODO: (flatten ellipse) use direct algorithm
384 return arcToCube(start, rx, ry, phi, large, sweep, end).Flatten(tolerance)
385}
386
387////////////////////////////////////////////////////////////////
388// Béziers /////////////////////////////////////////////////////

Callers 4

FlattenMethod · 0.85
ToVectorRasterizerMethod · 0.85
ToScanxScannerMethod · 0.85
TestFlattenEllipseFunction · 0.85

Calls 8

MoveToMethod · 0.95
LineToMethod · 0.95
EqualFunction · 0.85
ellipseToCenterFunction · 0.85
PolarPointFunction · 0.85
arcToCubeFunction · 0.85
FlattenMethod · 0.80
AddMethod · 0.45

Tested by 1

TestFlattenEllipseFunction · 0.68