I tried to draw a circle flipped vertically by its center. (Flipping a circle by its center looks same so that I can check visually). But the drawn position is entirely wrong. I expect that the fill has to be occurred entirely inside the stroked region
circleRect = CGRect(x:100, y:100, width:100, height: 100)
override func draw(_ dirtyRect: CGRect) {
let ctx = NSGraphicsContext.current()!.cgContext
if(drawCircle) {
let path = getOvalPath(circleRect) //returns a oval cgpath for the rect, here the rect is a square so it gives a circle
//stroked without flipping
ctx.addPath(path)
ctx.setStrokeColor(CGColor.black)
ctx.strokePath()
//filled with flipping
ctx.saveGState
ctx.translateBy(x: 0, y: circleRect.size.height)
ctx.scaleBy(x: 1, y: -1)
ctx.addPath(path)
ctx.setFillColor(fillColor)
ctx.fillPath()
ctx.restoreGState()
}
drawCircle = true
setNeedsDisplay(circleRect)
Your circle's center is at (100, 100). Consider the effects of your transforms on that point:
var point = CGPoint(x: 100, y: 100)
// point = (100, 100)
point = point.applying(CGAffineTransform(scaleX: 1, y: -1))
// point = (100, -100)
point = point.applying(CGAffineTransform(translationX: 0, y: 100))
// point = (100, 0)
So your transforms move the center of the circle.
You're thinking about “flipping” the y axis, moving it from the bottom left corner of some “canvas” to the top left corner. Your circle will stay put if it is centered vertically on that canvas. Your canvas's height is implicitly defined by the y translation you apply, which is 100. So your canvas has height 100, which means the circle's center would need to be at y = 100/2 = 50 to stay put.
Since your circle's center is at y = 100, you need to use a canvas height of 2*100 = 200 to make the circle stay put.