Ich nehme an, Sie die Pfanne verarbeiten kann, und Sie können den Touch-Punkt gelangen. Was Sie wollen, ist die Projektion des Berührungspunktes auf die rote Linie zu berechnen und den UIView dort zu platzieren.
Die rote Linie steht senkrecht auf AB und besteht aus dem Mittelpunkt von AB.
//
//when the pan gesture recognizer reports state change event
/*you have
CGPoint A;
CGPoint B;
CGPoint T; //touch point
*/
//midpoint
CGPoint M = {(A.x+B.x)/2, (A.y+B.y)/2};
//AB distance
CGFloat distAB = sqrtf(powf(B.x-A.x, 2) + powf(B.y-A.y, 2));
//direction of the red line with unit length
CGVector v = {(B.y-A.y)/distAB, -(B.x-A.x)/distAB};
// vector from midpoint to touch point
CGVector MT = {T.x-M.x, T.y-M.y};
// dot product of v and MT
// which is the signed distance of the projected point from M
CGFloat c = v.dx*MT.dx + v.dy*MT.dy;
// projected point is M + c*v
CGPoint projectedPoint = {M.x + c*v.dx, M.y + c*v.dy};
//TODO: set the center of the moving UIView to projectedPoint
UPDATE:
Ihr Kommentar zeigt, dass die Nutzung dieses soulution für Sie nicht klar genug ist. Deshalb habe ich diese Idee in ein funktionierendes Beispiel eingebettet.
@interface ViewController()
@end
@implementation ViewController {
CGPoint A;
CGPoint B;
CGPoint M; //midpoint of AB
CGVector v; //direction of the red line with unit length
UIView* pointMover;
}
- (void)viewDidLoad {
[super viewDidLoad];
A = CGPointMake(50,50);
B = CGPointMake(300,200);
M = CGPointMake((A.x+B.x)/2, (A.y+B.y)/2);
CGFloat distAB = sqrtf(powf(B.x-A.x, 2) + powf(B.y-A.y, 2));
v = CGVectorMake((B.y-A.y)/distAB, -(B.x-A.x)/distAB);
pointMover = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 44, 44)];
pointMover.center = M;
pointMover.backgroundColor = [UIColor blueColor];
pointMover.layer.cornerRadius = 22.0f;
[self.view addSubview:pointMover];
UIPanGestureRecognizer* panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
[pointMover addGestureRecognizer:panRecognizer];
UIBezierPath* blackLinePath = [UIBezierPath bezierPath];
[blackLinePath moveToPoint:A];
[blackLinePath addLineToPoint:B];
CAShapeLayer *blackLineLayer = [CAShapeLayer layer];
blackLineLayer.path = [blackLinePath CGPath];
blackLineLayer.strokeColor = [[UIColor blackColor] CGColor];
blackLineLayer.lineWidth = 2.0;
[self.view.layer addSublayer:blackLineLayer];
}
- (void)handlePan:(UIPanGestureRecognizer*)recognizer {
//touch point
CGPoint T = [recognizer locationInView:self.view];
// vector from midpoint to touch point
CGVector MT = {T.x-M.x, T.y-M.y};
// dot product of v and MT
CGFloat c = v.dx*MT.dx + v.dy*MT.dy;
// projected point is M + c*v
CGPoint projectedPoint = {M.x + c*v.dx, M.y + c*v.dy};
pointMover.center = projectedPoint;
}
@end
vielleicht haben Sie meine Bedenken missverstanden, der Punkt sollte beginnen, sich von der Mitte der Linie zu bewegen, die Sie in der aktualisierten Frage sehen können. –
auch, wenn der Benutzer den Mittelpunkt an einem bestimmten Punkt setzt und die Neupositionierung erneut beginnt, dann von dort nur nicht vom Mittelpunkt des Mittelpunkts aus beginnt. –