2

I've been doing some shape drawing using Swift's built in drawing tools to draw simple paths with straight lines. One anomaly I've noticed is that if you want a path that is filled but does not have a line stroke on its edge, it renders without antialiasing and has a rough appearance. In contrast, a line by default always renders smoothly. There is an option to turn antialiasing on but this also makes no difference. I could just make the stroke the same colour as the fill, but this means that the edge expands outwards from the point positions that define the shape.

   //creates shape node to contain path
            let myTriangle = SKShapeNode()
    //declares path object
            let myPath = CGPathCreateMutable()
    //moves to starting point of shape
            CGPathMoveToPoint(myPath, nil, -50, 0)
    //draws lines of shape
            CGPathAddLineToPoint(myPath, nil, 0, 100 )
            CGPathAddLineToPoint(myPath, nil, 50, 0 )
            CGPathAddLineToPoint(myPath, nil, -50, 0 )
    //closes path
            CGPathCloseSubpath(myPath)

            myTriangle.antialiased = true
//adds path to shape node
            myTriangle.path = myPath
//sets fill colour and zero line width
            myTriangle.fillColor = SKColor.blueColor()
            myTriangle.lineWidth = 0
//sets antialiasing
            myTriangle.antialiased = true
//sets position in parent object and adds node
            myTriangle.position = CGPointMake(600, 600)
            self.addChild(myTriangle)

Any ideas?

Many thanks, Kw

Kwangle
  • 349
  • 2
  • 15
  • can you provide some screenshots illustrating the problems, and the ideal? – Confused Jan 27 '17 at 13:58
  • Here is an example I created. The triangle has the code I posted except for the leftmost point which I moved to show the edge more clearly. Note the red box and black circles have a white line and are perfectly smooth. The red box is rotating and still rendering perfectly. I magnified the picture 200% so I hope you can see the difference: http://imgur.com/a/ypPFk – Kwangle Jan 27 '17 at 15:19
  • This is a bit surprising. If you stroke the triangle, it looks fine? – Maury Markowitz Jan 27 '17 at 18:23

1 Answers1

1

About the antialiasing you can take a look here to this document. I've seen also you have a lineWidth equal to 0, that's not help according with this document..

To improve the appearance of your path you could try also:

yourPath.lineCap = CGLineCap(rawValue: 1)!

where, following the source:

/* Line cap styles. */
public enum CGLineCap : Int32 {   
    case butt
    case round
    case square
}

Some code to example written in Swift 3:

        let myTriangle = SKShapeNode()
        let myPath = CGMutablePath()
        myPath.move(to: CGPoint(x:-110,y: 0))
        myPath.addLine(to: CGPoint(x:0,y: 290))
        myPath.addLine(to: CGPoint(x:260,y: 0))
        myPath.addLine(to: CGPoint(x:-110,y: 0))
        myPath.closeSubpath()
        myTriangle.path = myPath
        myTriangle.fillColor = SKColor.white
        myTriangle.lineWidth = 2
        myTriangle.lineCap = CGLineCap(rawValue: 1)!
        myTriangle.strokeColor = SKColor.white
        myTriangle.isAntialiased = true
        myTriangle.position = CGPoint(x:self.frame.midX,y:self.frame.midY)
        self.addChild(myTriangle)

The Output of this code (lineWidth 2 and lineCap valorized..):

enter image description here

Your Output (lineWidth equal to 0):

enter image description here

Alessandro Ornano
  • 34,887
  • 11
  • 106
  • 133
  • I think that just alters the way line ends and corners render, in a similar way to Adobe Illustrator. – Kwangle Jan 27 '17 at 15:21
  • @Kwangle I've added some code to help your research – Alessandro Ornano Jan 27 '17 at 23:43
  • Yes that's fine, but I want smoothed edges without having to draw a stroke around the path. It seems that Swift only allows smoothing fro stroked paths. I needed precise object boundaries as I was using shapes to check collision detection code so adding a few pixels of width is not desirable. Many thanks for your research and input, however. – Kwangle Jan 28 '17 at 11:26
  • `SKShapeNode` have some limitations , that's sure, but if you subtract a reasonable width like 2 points from your shape dimensions you should solve your problem, especially because the stroke have the same color of the shape. About checking collision, how do you check collision? Are you using physics engine? – Alessandro Ornano Jan 28 '17 at 11:33
  • Yes but it can get awkward to calculate that inset for irregular shapes, and this does seem like an odd omission for SpriteKit. I'm writing my own collision detection routines as an exercise and have got circle to circle and circle to angled boxes working. Thanks again for your help. – Kwangle Jan 28 '17 at 12:37
  • You could always use `.intersects(<#T##node: SKNode##SKNode#>)` or `.contains(<#T##p: CGPoint##CGPoint#>)` to handle your collisions. – Alessandro Ornano Jan 28 '17 at 12:47