swiftsprite-kitskspritenodecentroidanchorpoint

calculate centroid of SKSpriteNode for anchor point


I have a SKSpriteNode which is an image of a equilateral triangle, I want to set it's anchor point at the triangle's centroid so I can get it to rotate smoothly and remain in centre. I have calculated the centroid with the code bellow but these positions are relative to the scene, so I'm not sure how to convert it to the accurate decimals for the anchor point (between 0 and 1).

    let XA = triangle.position.x - (triangle.size.width / 2) // left point
    let XB = triangle.position.x // top point
    let XC = triangle.position.x + (triangle.size.width / 2) // right point

    let YA = triangle.position.y - (triangle.size.height / 2) // left point
    let YB = triangle.position.y + (triangle.size.height / 2) // top point
    let YC = triangle.position.y - (triangle.size.height / 2) // right point

    let triCenterX = (XA + XB + XC) / 3.0
    let triCenterY = (YA + YB + YC) / 3.0

    let centroid = CGPointMake(triCenterX, triCenterY) // 207.0, 412.65

    // triangle.anchorPoint = CGPoint(x: , y: )

I'm not sure if I'm on the right track or where to go from here, maybe I need to do this a different way? Any help would be much appreciated, thanks.


Solution

  • If I understand you correctly, this is what you are seeing right now:

    Rotating around default anchor point

    Yellow dot represents the centroid of triangles bounding box. Transparent white rectangle represents the bounding box of a triangle. The black dot is actual centroid of equilateral triangle. So, right now, triangle's texture is being rotated around yellow dot? Right?

    But you want something like this:

    Rotating around modified anchor point

    You want to shift the texture a bit upwards so it looks like that triangle is being rotated around its centroid?

    If so, I did this by calculating A,B and C points of a triangle in triangle's coordinate space, like this:

    let xa = -triangle.size.width / 2.0
    let xb = triangle.size.width /  2.0
    let xc = CGFloat(0.0)
    
    let ya = -triangle.size.height / 2.0
    let yb = -triangle.size.height / 2.0
    let yc = triangle.size.height / 2.0
    

    Then, based on the formula for calculating centroid of equilateral triangle, I've calculated the triangle's centroid:

    let centroidX = (xa + xb + xc ) / 3.0
    let centroidY = (ya + yb + yc) / 3.0     
    let centroid = CGPoint(x: centroidX, y: centroidY)
    

    and calculated the new anchor point based on centroid position:

    let anchorX =  centroidX / triangle.size.width
    let anchorY = centroidY / triangle.size.height
    let anchor = CGPoint(x: anchorX + triangle.anchorPoint.x, y: anchorY + triangle.anchorPoint.y)
    

    This is the image I've used:

    Equilateral triangle