Rotate UIImageView 1 degree - xcode

I have this code for rotate image view:
func rotateAgain(){
UIView.animateWithDuration(1.0,
delay: 0.0,
options: .CurveLinear,
animations: {self.imageView.transform = CGAffineTransformRotate(self.imageView.transform, 1.degreesToRadians)},
completion: {finished in if self.rotating { self.rotateOnce() }})
}
What is wrong in the code?

The second argument for the CGAffineTransformRotate is for the angle, but it is in radians, if you want to transform radians to degrees, you have to multiply the angle in degrees with 0.0174532925
Example for rotating for 240 degrees:
CGAffineTransformRotate(self.imageView.transform, 240 * 0.0174532925)

Related

Animating a view in a real time

I am trying to create animation that is connected to real time.
I have two points on my screen and an image moves between them. So for example I have an image that is at the Strat point at 12:00 and I want it to be at the end point at 12:10.
func animate_this_image(start: Date, end: Date, imageView: UIImageView, start_point: CGPoint, end_point: CGPoint) {
let duration = end.timeIntervalSince(start)
let frame = CGRect(x: end_point.x, y: end_point.y, width: 60, height: 60).offsetBy(dx: -30, dy: -30)
UIView.animate(withDuration: duration) {
imageView.frame = frame
}
}
My problem is that I want it to be connected to the actual clock. So for example if I close the view at 12:02 and open it at 12:09 I want the image to be at the correct place between the two point (roughly at the end). Instead at the moment the image starts again from the start point. That is happening because I just take the two dates and use the difference as the animation duration.
Anyone that has had similar problem or a suggestion on how I can solve this?
This is connected to a map. I have two points and a poly line between the points. I wanted an image to glide between the points. I could not figure anything easy with the map so I created a view on top of the map that has the image view on. I transfer the points from the map to the other view to get the start and stop points. Maybe there is a better way to do this by using the map?
Cheers,
Jonas
This was easier than I thought... this is my solution
func animate_this_image(start: Date, end: Date, imageView: UIImageView, start_point: CGPoint, end_point: CGPoint) {
// find the total duration and the time left until reaching next point
let duration = end.timeIntervalSince(start)
let time_left = end.timeIntervalSince(Date())
// the percentage is used to calculate how far is left on the line
let percentage = time_left / duration
//calculate the correct point at this time
let x_dist = (end_point.x - start_point.x) * CGFloat(percentage)
let y_dist = (end_point.y - start_point.y) * CGFloat(percentage)
imageView.frame = CGRect(x: end_point.x - x_dist, y: end_point.y - y_dist, width: 60, height: 60).offsetBy(dx: -30, dy: -30)
// define end point
let frame = CGRect(x: end_point.x, y: end_point.y, width: 60, height: 60).offsetBy(dx: -30, dy: -30)
// Then animate it
UIView.animate(withDuration: time_left) {
imageView.frame = frame
}
}

How to calculate rotation just like in MotionBuilder

Problem:
My goal is to write a code, that rotates the root joint of a bvh, θ degrees around global y axis3, and keeps values in the range of -180 to 180 (just like MotionBuilder does). I have tried to rotate a joint using euler, quaternions, matrices (considering the rotational order of a bvh) but I haven't yet figured out how to get the correct values. MotionBuilder calculates the values x,y,z so they are valid for the bvh file. I would like to write a code that calculates the rotation x,y,z for a joint, just like in MotionBuilder.
Example:
Initial: Root rotation: [x= -169.56, y=15.97, z=39.57]
After manually rotating about 45 degrees: Root rotation: [x=-117.81, y=49.37, z=70.15]
global y axis:
To rotate a node around the world Y axis any number of degrees the following works (https://en.wikipedia.org/wiki/Rotation_matrix):
import math
from pyfbsdk import *
angle = 45.0
radians = math.radians(angle)
root_matrix = FBMatrix()
root.GetMatrix(root_matrix, FBModelTransformationType.kModelRotation, True)
transformation_matrix = FBMatrix([
math.cos(radians), 0.0, math.sin(radians), 0.0,
0.0, 1.0, 0.0, 0.0,
-math.sin(radians), 0.0, math.cos(radians), 0.0,
0.0, 0.0, 0.0, 1.0
])
result_matrix = root_matrix * transformation_matrix
root.SetMatrix(result_matrix , FBModelTransformationType.kModelRotation, True)
If there are any Pre-Rotations on the root node the process is more complex and you can try setting the Rotations using the SetVector with the LRMToDof method.
result_vector = FBVector3d()
root.LRMToDof(result_vector, result_matrix)
root.SetVector(result_vector, FBModelTransformationType.kModelRotation, True)

Rotate CIImage in Swift 2 using CGAffineTransformMakeRotation

I try and rotate a CIImage in Swift2 using
let rotatedImage = someCIImage.imageByApplyingTransform(CGAffineTransformMakeRotation(CGFloat(M_PI / 2.0))))
When I look at the sized of the resulting rectangle, it has been rotated. (it was 1000x500 and now is 500x1000). However, the calculations I do subsequently (convert to bitmap and access individual pixels) indicate differently. Am I right that the the above transformation rotates around the center of the image, i.e. in the above example around 500/250?
That transform rotates around the image's origin. This version sets the pivot point to the centre:
var tx = CGAffineTransformMakeTranslation(
image.extent.width / 2,
image.extent.height / 2)
tx = CGAffineTransformRotate(
tx,
CGFloat(M_PI_2))
tx = CGAffineTransformTranslate(
tx,
-image.extent.width / 2,
-image.extent.height / 2)
var transformImage = CIFilter(
name: "CIAffineTransform",
withInputParameters: [
kCIInputImageKey: image,
kCIInputTransformKey: NSValue(CGAffineTransform: tx)])!.outputImage!
Simon
In Swift 5, the code gets nicer. This is a CIImage extension method to easily rotate itself around the center.
func rotate(_ angle: CGFloat) -> CIImage {
let transform = CGAffineTransform(translationX: extent.midX, y: extent.midY)
.rotated(by: angle)
.translatedBy(x: -extent.midX, y: -extent.midY)
return applyingFilter("CIAffineTransform", parameters: [kCIInputTransformKey: transform])
}

How to make clock ticks stuck to the clock border?

I try to make a clock, in swift, but now i want to make something strange. I want make border radius settable. This is the easy part (is easy because I already did that). I drew 60 ticks around the clock. The problem is that 60 ticks are a perfect circle. If I change the border radius I obtain this clock:
All ticks are made with NSBezierPath, and code for calculate position for every tick is :
tickPath.moveToPoint(CGPoint(
x: center.x + cos(angle) * point1 ,
y: center.y + sin(angle) * point1
))
tickPath.lineToPoint(CGPoint(
x: center.x + cos(angle) * point2,
y: center.y + sin(angle) * point2
))
point1 and point2 are points for 12 clock tick.
My clock background is made with bezier path:
let bezierPath = NSBezierPath(roundedRect:self.bounds, xRadius:currentRadius, yRadius:currentRadius)
currentRadius - is a settable var , so my background cam be, from a perfect circle (when corner radius = height / 2) to a square (when corner radius = 0 ).
Is any formula to calculate position for every tick so, for any border radius , in the end all ticks to be at same distance to border ?
The maths is rather complicated to explain without recourse to graphics diagrams, but basically if you consider a polar coordinates approach with the origin at the clock centre then there are two cases:
where the spoke from the origin hits the straight side of the square - easy by trigonometry
where it hits the circle arc at the corner - we use the cosine rule to solve the triangle formed by the centre of the clock, the centre of the corner circle and the point where the spoke crosses the corner. The origin-wards angle of that triangle is 45º - angleOfSpoke, and two of the sides are of known length. Solve the cosine equation as a quadratic and you have it.
This function does it:
func radiusAtAngle(angleOfSpoke: Double, radius: Double, cornerRadius: Double) -> Double {
// radius is the half-width of the square, = the full radius of the circle
// cornerRadius is, of course, the corner radius.
// angleOfSpoke is the (maths convention) angle of the spoke
// the function returns the radius of the spoke.
let theta = atan((radius - cornerRadius) / radius) // This determines which case
let modAngle = angleOfSpoke % M_PI_2 // By symmetry we need only consider the first quadrant
if modAngle <= theta { // it's on the vertical flat
return radius / cos(modAngle)
} else if modAngle > M_PI_2 - theta { // it's on the horizontal flat
return radius / cos(M_PI_2 - modAngle)
} else { // it's on the corner arc
// We are using the cosine rule to solve the triangle formed by
// the clock centre, the curved corner's centre,
// and the point of intersection of the spoke.
// Then use quadratic solution to solve for the radius.
let diagonal = hypot(radius - cornerRadius, radius - cornerRadius)
let rcosa = diagonal * cos(M_PI_4 - modAngle)
let sqrTerm = rcosa * rcosa - diagonal * diagonal + cornerRadius * cornerRadius
if sqrTerm < 0.0 {
println("Aaargh - Negative term") // Doesn't happen - use assert in production
return 0.0
} else {
return rcosa + sqrt(sqrTerm) // larger of the two solutions
}
}
}
In the diagram OP = diagonal, OA = radius, PS = PB = cornerRadius, OS = function return, BÔX = theta, SÔX = angleOfSpoke

Rotate image on its own center kineticJS

I'm trying to rotate an image added to my canvas using KineticJS.
I got it almost working.
I know I need to set the offset to 'move' the rotation point, that part is working.
But it is also moving to that location of the offset.
After doing some rotating I can drag my image to another location in the canvas and continue rotating around its own center.
I don't want to rotate the whole canvas, because I have multiple images on a layer.
The relevant code:
function rotateLayer() {
// Rotate bird image
var rotation = 15;
// Set rotation point:
imageDict[1].setOffsetX(imageDict[1].width() / 2);
imageDict[1].setOffsetY(imageDict[1].height() / 2);
// rotation in degrees
imageDict[1].rotate(rotation);
imageDict[1].getLayer().draw();
}
A working demo is on jsfiddle: http://jsfiddle.net/kp61vcfg/1/
So in short I want the rotation but not the movement.
How you want to rotate without movement?
KineticJS rotate objects relative it's "start point" . For example for Kinetic.Rect start points is {0, 0} - top left corner. You may move such "start point" to any position with offset params.
After a lot of trail and error I found the solution.
The trick is to set the offset during load to the half width and height to set the rotation point to the middle of the image AND don't call image.cache:
function initAddImage(imgId, imgwidth, imgheight) {
var imageObj = new Image();
imageObj.src = document.getElementById(imgId).src;
imageObj.onload = function () {
var image = new Kinetic.Image({
image: imageObj,
draggable: true,
shadowColor: '#787878',
shadowOffsetX: 2,
shadowOffsetY: 2,
width: imgwidth,
height: imgheight,
x: 150, // half width of container
y: 150, // half height of container
offset : {x : imgwidth / 2, y : imgheight / 2}, // Rotation point
imgId: imgId
});
layer.add(image);
//image.cache();
layer.draw();
imageDict[currentLayerHandle] = image;
currentLayerHandle++;
};
}
I've updated my demo to a working version:
http://jsfiddle.net/kp61vcfg/2/

Resources