iOS牛顿摆 小球撞击 物理学仿真模拟

来源:互联网 发布:linux set locale 编辑:程序博客网 时间:2024/04/30 21:27
                        **第一次写博客有点激动呢**

牛顿摆模型
使用 UIDynamic 的方法就不叙述了
这里先讲一下 牛顿摆是经过计算的一个公式才能达到理想状态 由于我不知道公式 所以做出来不能完美的达成 一个小球落下来另一个小球飞起来

接下来直接上代码 代码中的描述还是很详细的

#import "ViewController.h"#import "ContentView.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];    ContentView *view =[[ContentView alloc]initWithFrame:self.view.bounds];    view.backgroundColor=[UIColor blueColor];    [self.view addSubview:view];}- (void)didReceiveMemoryWarning {    [super didReceiveMemoryWarning];    // Dispose of any resources that can be recreated.}@end
#import "ContentView.h"#import "BallsView.h"@interface ContentView(){    UIDynamicAnimator *_animator;//仿真模拟器    NSMutableArray *_arrayBalls;    CGPoint _centers[100];//可变的小球中心坐标    UISnapBehavior *_snapB;    UIAttachmentBehavior *attachement1;}@endstatic CGFloat radius=20;//小球半径static CGFloat attachmentLenth=500;//链接长度@implementation ContentView-(id)initWithFrame:(CGRect)frame{    if (self=[super initWithFrame:frame]) {        //初始化仿真模拟器        _animator=[[UIDynamicAnimator alloc]initWithReferenceView:self];        //初始化所有仿真元素 就是小球        [self creatBalls];        //添加小球的行为元素        [self addBehavior];        //利用 drawRect 方法绘制小球和锚点的连线        //使用 touchBegan方法判断我们要抓住的小球 用 touchMove的方法使我们的小球随着手指滑动 使用 touchEnd 方法移除 snap 行为释放小球    }    return  self;}static int b;-(void)addBehavior{    //这样的方法要经常使用 可以避免程序的崩溃    if (!_arrayBalls.count) {        return;    }    //仿真元素的行为描述    UIDynamicItemBehavior *itemBehavior=[[UIDynamicItemBehavior alloc]initWithItems:_arrayBalls];    itemBehavior.elasticity=1.00001;//弹性    itemBehavior.resistance=.01;//阻尼    itemBehavior.density=1000;//密度    itemBehavior.allowsRotation=NO;//禁止旋转    [_animator addBehavior:itemBehavior];    //因为我们的小球都需要重力行为直接添加上就可以了    UIGravityBehavior *gravityB=[[UIGravityBehavior alloc]initWithItems:_arrayBalls];    gravityB.magnitude=10;//重力加速度    [_animator addBehavior:gravityB];    //添加碰撞行为    UICollisionBehavior *collisionB=[[UICollisionBehavior alloc]initWithItems:_arrayBalls];    [_animator addBehavior:collisionB];    //添加链接行为 链接行为是将两个点相连    for (int i=0; i<_arrayBalls.count; i++) {        UIAttachmentBehavior *attachmentB=[[UIAttachmentBehavior alloc]initWithItem:_arrayBalls[i] attachedToAnchor:_centers[i]];        attachmentB.length=attachmentLenth;        attachmentB.damping=0;        attachmentB.frequency=0;        [_animator addBehavior:attachmentB];    }}-(void)creatBalls{    _arrayBalls=[[NSMutableArray alloc]initWithCapacity:1];    //计算小球中心的坐标    for (int i=0; i<6; i++) {        CGPoint p=CGPointMake(60+i*2*radius+i*3, 30);        _centers[i]=p;    }    for (int i=0; i<6; i++) {        //这里创建一个小球的 view        BallsView *ball=[[BallsView alloc]initWithFrame:CGRectMake(0, 0, 2*radius, 2*radius) withRadius:radius];        //在这里确定小球的初始位置        ball.center=_centers[i];        //这里添加的 kvo 方法作用是当监听到小球的中心变化时 执行 setNeedDisplay 方法 走了这方法后 就会重新绘制contentView        [ball addObserver:self forKeyPath:@"center" options:NSKeyValueObservingOptionNew context:nil];        [self addSubview:ball];        [_arrayBalls addObject:ball];    }}- (void)drawRect:(CGRect)rect {    //绘图第一点 获取上下文    CGContextRef context=UIGraphicsGetCurrentContext();    //绘制连接线    for (int i=0; i<6; i++) {        UIView *view=_arrayBalls[i];        CGContextMoveToPoint(context, _centers[i].x, _centers[i].y);        CGContextAddLineToPoint(context,view.center.x, view.center.y);    }    CGContextStrokePath(context);}-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{    [self setNeedsDisplay];}-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{    UITouch *touch=[touches anyObject];    for (int i=0; i<6; i++) {        UIView *view=_arrayBalls[i];        CGPoint point=[touch locationInView:view];        if ([view pointInside:point withEvent:nil]) {            //NSLog(@"%d",i);            b=i;        }    }}-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{    if (_snapB==nil) {        UITouch *touch=[touches anyObject];        CGPoint point=[touch locationInView:self];        _snapB=[[UISnapBehavior alloc]initWithItem:_arrayBalls[b] snapToPoint:point];        //NSLog(@"%d",b);        [_animator addBehavior:_snapB];    }else{        [_animator removeBehavior:_snapB];        _snapB=nil;    }}-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{    [_animator removeBehavior:_snapB];}@end
#import <UIKit/UIKit.h>@interface BallsView : UIView-(id)initWithFrame:(CGRect)frame withRadius:(CGFloat)radius;@end
#import "BallsView.h"@implementation BallsView-(id)initWithFrame:(CGRect)frame withRadius:(CGFloat)radius{    if (self =[super initWithFrame:frame]) {        //初始化小球的属性        self.layer.cornerRadius=radius;         self.layer.borderColor=[UIColor greenColor].CGColor;        self.layer.borderWidth=2;        self.backgroundColor=[UIColor yellowColor];        self.layer.shadowColor=[UIColor blackColor].CGColor;        self.layer.shadowRadius=.5;    }    return self;}@end

见笑了做的并不好看

1 0
原创粉丝点击