Finding position of pentagon inside circle - ios

I'm trying to draw small circles over corners of pentagon inside a circle.
I know the following information.
The radius of circle is 50.
Centre of circle is x = 100, y = 100
How can I get position of pentagon corners in x and y so that I can draw a circle there.
Thanks.

I hope you are familiar with polar coordinates. I wrote simple algorithm to calculate corners:
let center = CGPoint(x: 100, y: 100)
let numberOfCorners: Int = 5
let radius = 50.0
var angle:Double = 0.0
let startAngle = M_PI_2
var points: [CGPoint] = []
angle = startAngle
while angle - startAngle < 2*M_PI {
let x = radius * cos(angle) + Double(center.x) // transform polar coordinates to XY
let y = radius * sin(angle) + Double(center.y)
let point = CGPoint(x: x, y: y)
points.append(point)
let angleIncrease = Double(2.0*M_PI)/Double(numberOfCorners)
angle += angleIncrease
}
print(points)
It should works with other polygons. You only have to specify numberOfCorners and startAngle (in radians). Correct StartAngle for iOS coordinates is I think: 3/2 PI.
But for default XY plane to achieve polygon like on your picture, pi/4 it's ok.

Related

Smooth open UIBezierPath

I'm trying to get smooth edges of Arcs and Curves.
The SKShapeNodes are open UIBezierPaths with a thick line-width, however, jagged edges are noticeable around Arcs and Curves. Changing the flatness doesn't seem to have any effect. Is there a way to smoothen these, or am I going to have to make a closed UIBezierPath with no line-width?
You need to create closed UIBezierPath with no linewidth
also
Make it shouldRasterize = true and set proper scale rasterizationScale = 2 * UIScreen.main.scale
I have a solution to my problem. Instead of using path.addArc(), I now use a function to get as many points as I'd like along an arc and then use path.addLine() to every one of those points. If you want more points for a smoother path, just lower the value of n.
func getCirclePoints(centerPoint: CGPoint, radius: CGFloat, startAngle: CGFloat, endAngle: CGFloat, clockwise: Bool) -> [CGPoint] {
let n : CGFloat = clockwise ? -1 : 1
let points: [CGPoint] = stride(from: startAngle - n, through: endAngle + n, by: n).map {
let degreesToRadians = CGFloat($0) * .pi / 180
let x = centerPoint.x + radius * cos(degreesToRadians)
let y = centerPoint.y + radius * sin(degreesToRadians)
return CGPoint(x: x, y: y)
}
return points
}

Swift: make rotation of point in 2D

I want to make a rotation of point by -90 degrees
Initial
Final
Let's take a look on top left and top right points of Initial. Their coordinates are:
let topLeft = CGPoint(x: 2, y: 1)
let topRight = CGPoint(x: 3, y: 1)
And after rotation coordinates of them should become:
topLeft 1:0
topRight 2:0
How can i do it ?
I have tried several answers but none of them give me my final results.
did not work:
Rotating a CGPoint around another CGPoint
What is the best way to rotate a CGPoint on a grid?
Here are some code from my playground:
let topLeft = CGPoint(x: 2, y: 1)
let topRight = CGPoint(x: 3, y: 1)
func rotatePoint1(_ point: CGPoint, _ degrees: CGFloat) -> CGPoint {
let s = CGFloat(sinf(Float(degrees)))
let c = CGFloat(cosf(Float(degrees)));
return CGPoint(x: c * point.x - s * point.y, y: s * point.x + c * point.y)
}
func rotatePoint2(_ point: CGPoint, _ degrees: CGFloat, _ origin: CGPoint) -> CGPoint {
let dx = point.x - origin.x
let dy = point.y - origin.y
let radius = sqrt(dx * dx + dy * dy)
let azimuth = atan2(dy, dx) // in radians
let newAzimuth = azimuth + degrees * CGFloat(M_PI / 180.0) // convert it to radians
let x = origin.x + radius * cos(newAzimuth)
let y = origin.y + radius * sin(newAzimuth)
return CGPoint(x: x, y: y)
}
func rotatePoint3(_ point: CGPoint, _ degrees: CGFloat) -> CGPoint {
let translateTransform = CGAffineTransform(translationX: point.x, y: point.y)
let rotationTransform = CGAffineTransform(rotationAngle: degrees)
let customRotation = (rotationTransform.concatenating(translateTransform.inverted())).concatenating(translateTransform)
return point.applying(customRotation)
}
print(rotatePoint1(topLeft, -90))
print(rotatePoint1(topRight, -90))
You are really describing two rotations with your example:
The points are rotated by -90 degrees around the center of the 3x3 grid. When this happens, the topLeft point becomes bottomLeft, and topRight becomes topLeft.
Then you rotate those points around the center of the square 90 degrees (ie. the other direction) to make them topLeft and topRight again.
Using this function from this answer:
func rotatePoint(target: CGPoint, aroundOrigin origin: CGPoint, byDegrees: CGFloat) -> CGPoint {
let dx = target.x - origin.x
let dy = target.y - origin.y
let radius = sqrt(dx * dx + dy * dy)
let azimuth = atan2(dy, dx) // in radians
let newAzimuth = azimuth + byDegrees * .pi / 180 // convert it to radians
let x = origin.x + radius * cos(newAzimuth)
let y = origin.y + radius * sin(newAzimuth)
return CGPoint(x: x, y: y)
}
let topLeft = CGPoint(x: 2, y: 1)
let topRight = CGPoint(x: 3, y: 1)
let squareCenter = CGPoint(x: 2.5, y: 1.5)
// First rotate around the center of the 3 x 3 square
let centerOfRotation = CGPoint(x: 1.5, y: 1.5)
let tl1 = rotatePoint(target: topLeft, aroundOrigin: centerOfRotation, byDegrees: -90) // (x 1 y 1)
let tr1 = rotatePoint(target: topRight, aroundOrigin: centerOfRotation, byDegrees: -90) // (x 1 y 0)
let sc1 = rotatePoint(target: squareCenter, aroundOrigin: centerOfRotation, byDegrees: -90) // (x 1.5 y 0.5)
// Now rotate the 1x1 square the other way around new position of square center
let tl2 = rotatePoint(target: tl1, aroundOrigin: sc1, byDegrees: 90) // (x 1 y 0)
let tr2 = rotatePoint(target: tr1, aroundOrigin: sc1, byDegrees: 90) // (x 2 y 0)
Note: As #MBo noted in the comments, if your cell is always 1x1, it is sufficient to rotate the center of your cell and then just add and subtract the 0.5 offsets to find the four corners.
You can just transform you view like so
yourView.transform = CGAffineTransform(rotationAngle: -CGFloat.pi/2)
EDIT:
My bad.
Use CGFloat.pi when working with degrees
print(rotatePoint1(topLeft, -CGFloat.pi/2))
Use sin and cos functions directly
let s = sin(degrees)
let c = cos(degrees)
iOS coordinate system is a bit flipped compared to standard one so you will have to adjust the angle (you can see simulation)
print(rotatePoint1(topLeft, -CGFloat.pi/2)) // (1.0000000000000002, -2.0)
print(rotatePoint1(topRight, -CGFloat.pi/2)) // (1.0000000000000002, -3.0)

Moving SpriteNodes outwards in a circular pattern

I have a function that creates 8 bullets coming from the player in a circle firing outwards. I think the problem lies with this line here:
let endPoint = CGPoint(x: distance * cos(angle), y: distance * sin(angle))
This causes the bullets to move faster in the bottom left of the circle than the ones in the top right, when in fact they should all move the same distance at the same speed.
Does anyone know how to implement this?
func fireSpecialWeapon() {
stride(from: 0, to: 2 * CGFloat.pi, by: 2 * CGFloat.pi / 8 ).forEach { angle in
let bullet = SKSpriteNode(imageNamed: "bulletCircle")
bullet.setScale(3)
bullet.zRotation = angle
bullet.position = player.position
bullet.zPosition = 2
//move outwards to the edge of the screen
let distance: CGFloat = 1000
let endPoint = CGPoint(x: distance * cos(angle), y: distance * sin(angle))
let move = SKAction.move(to: endPoint, duration: 2)
self.addChild(bullet)
bullet.run(move)
}
}
if the bullets are moving faster from the bottom left then the top right, that means your anchor points are (0,0) not (0.5,0.5)

How can I draw line intersecting the arc perpendicularly(Core Graphics)?

I want to draw a line on the circle(intercepting the arc of the circle) perpendicularly like in the picture.
I am using this code to draw circle
let center = CGPoint(x: bounds.width / 2, y: bounds.height / 2)
let path = UIBezierPath(arcCenter: center, radius: radius, startAngle: Conversion.degreesToRadians(value: CGFloat(0)), endAngle: Conversion.degreesToRadians(value: CGFloat(360)), clockwise: true)
path.lineWidth = 2
path.lineCapStyle = CGLineCap.square
UIColor.white.setStroke()
path.stroke()
The basic idea is that a circle has a certain radius about a center CGPoint. To figure out a point on the circle, you can calculate the x and y coordinates like so:
func point(center: CGPoint, radius: CGFloat, angle: CGFloat) -> CGPoint {
let x = center.x + radius * cos(angle)
let y = center.y + radius * sin(angle)
return CGPoint(x: x, y: y)
}
where the angle is measured in radians, starting at 3 o'clock and going clockwise.
So those perpendicular intersecting strokes are merely line segments between two CGPoint at a given angle, where the "radius" used for the start of the line segment might be, for example, something just less than the radius of the circle. For the ending point of the line, use the same angle, but then use a radius value just greater than the radius of the circle.

Swift creating angles on button click, but in opposit direction

I am creating a circle (Using CGContext) with angle of 90, 180 & 280. As we know that 90 degree angle shape like letter 'L', but I am getting opposite shape of 'L', then Angles.
Following this image, I don't want to get it like this, so what can I do ? please let me know.
Thanks
You can fix it with one of following solution.
1) Rotate your view (button) to -90 degree.
Or
2) Trickle values of angle while drawing as following:
func drawCircle(angles : Double) {
let angleToDraw = angles - 90
let startCircleAngle = CGFloat(269.9/180 * M_PI)
let endCircleAngle = CGFloat(270/180 * M_PI)
let center = CGPointMake(self.frame.size.width / 2.0, self.frame.size.height / 2.0);
let ctx = UIGraphicsGetCurrentContext()
CGContextBeginPath(ctx!)
CGContextSetLineWidth(ctx!, 5)
CGContextSetStrokeColorWithColor(ctx!,UIColor.redColor().CGColor)
let x:CGFloat = center.x
let y:CGFloat = center.y
let radius: CGFloat = 100.0
CGContextAddArc(ctx!, x, y, radius, startCircleAngle , endCircleAngle, 1)
CGContextAddArc(ctx!, x, y, 1, startCircleAngle, startCircleAngle, 0)
CGContextSaveGState(ctx!)
CGContextTranslateCTM(ctx!, x, y)
// rotation supplied in radians
CGContextRotateCTM(ctx!, CGFloat(M_PI*(angleToDraw)/180))
CGContextStrokePath(ctx!)
let path = CGPathCreateMutable()
CGPathMoveToPoint(path, nil, 0, 0)
CGPathAddLineToPoint(path, nil, radius, 1)
CGContextAddPath(ctx!, path)
CGContextSetLineWidth(ctx!, 4)
CGContextScaleCTM(ctx!, -1.0, 1.0)
CGContextSetStrokeColorWithColor(ctx!,UIColor.blackColor().CGColor)
CGContextStrokePath(ctx!)
}

Resources