iOS开发之随机生成两圆之间的标准圆

前言

相信很多社交产品中,肯定会存在寻找附近人或者附近商家的需求,类似下图,在大圆和小圆之间(橘色区域)生成一系列的随机圆,并且所有随机圆之间也不能有交集,我暂且称这种圆为标准圆。

关于这样的需要以前在做项目中有同事做过,虽然可以实现了上面的效果图,但是坐标及半径都是写死,从写死的数据随机取值,看上去是满足了,但是对于用户来说多次使用该功能时,肯定有一定的视觉疲倦,且写死的一些数据真的不好写,如果大圆或者小圆半径变化了,或者需要更多的标准圆,那怎么办呢?一脸懵逼????

实现思路

思路一:

对于这个需求,我一开始也陷入了写死数据的套路,但是在兼容大小圆半径上做了一定的兼容,大致的将大圆切分成 9块 ,然后在除了中间区域外的8块区域再生成一系列的伪标准圆。然后取值时现随机选取8块区域,再随机从块区拿取 伪标准圆 :

很明显,在 1、3、6、8 块中及中间块 存在很大的误差,明显也不可取

思路二:

根据数学思路,寻找标准圆:

1、在大圆内部生成 随机圆1 ,也就是生成内含圆:(其中只有圆1才是该步骤所需要的 随机圆1 )

对应的数学公式,当圆心距小于两圆半径之差时 两圆内含:

大圆中心坐标为(px1、py1),半径为R; 随机圆中心坐标为(px2、py2),半径为r

Objective-c代码如下:

 // 1: 判断随机生成的 圆 包含在 self 这个大圆内部
 if ( sqrt(pow(self.center.x - randomCPX, 2) + pow(self.frame.size.height / 2 - randomCPY, 2)) < (R - r) ) {

 }

2、从第1步得到的随机圆1中,筛选出和小圆不相交 随机圆2 :(其中只有圆1才是该步骤所需要的 随机圆2 )

对应的数学公式,当圆心距大于两圆半径之和时 两圆外离:

小圆中心坐标为(px1、py1),半径为Rr; 随机圆 中心坐标为(px2、py2),半径为r

Objective-c代码如下:

 // 2: 判断随机生成的 圆 不在 中间 这个圆 不能重合, 即得到两个圆之间的小圆
 if (sqrt(pow(self.center.x - randomCPX, 2) + pow(self.frame.size.height / 2 - randomCPY, 2)) > (Rr + r)) {

 }

3、从第2步得到的随机圆2中,筛选出和已存在的 标准圆 不相交 随机圆3 , 随机圆3 即我们所需要的 标准圆 (其中圆2是已经存在的 标准圆 ,那么只有圆1才是该步骤所需要的 随机圆3 )

对应的数学公式,当圆心距小于两圆半径之和时 两圆相交或两圆内含,随机圆2应该废弃:

存在的标准圆中心坐标为(px、py),半径为rr; 随机圆中心坐标为(px2、py2),半径为r

Objective-c代码如下:

// 3: 新生成的 圆 和已经存在的 圆 不能重合
 BOOL success = YES;
for (NSValue *value in randomCircleInfos) {
 CircleInfo circle;
 [value getValue:&circle];
 // 只要新生成的 圆 和 任何一个存在的 圆 有交集,则失败
if (sqrt(pow(circle.center.x - randomCPX, 2) + pow(circle.center.y - randomCPY, 2)) <= (circle.radius + r)) {
 success = NO; break ;
}
}
if (success) { [randomCircleInfos addObject:[self standardCircle:randomCPX centerY:randomCPY radius:r]];}为了寻找 8 个标准圆一共生成了 53 个随机圆 生成了 29 个在大圆内部的圆 生成了 9 个在大圆内部的圆且不与中圆有交集的圆 为了寻找 8 个标准圆一共生成了 38 个随机圆 生成了 28 个在大圆内部的圆 生成了 10 个在大圆内部的圆且不与中圆有交集的圆

只要通过这三步成功后,即得到了我们所要的标准圆,从算法的时间复杂度看 ,得到标准圆的复杂度为O(n*n),对于小量了标准圆来说,速度是非常快的:(当然效率上还由随机圆的半径有关系)

为了寻找 8 个标准圆一共生成了 53 个随机圆 生成了 29 个在大圆内部的圆 生成了 9 个在大圆内部的圆且不与中圆有交集的圆  为了寻找 8 个标准圆一共生成了 38 个随机圆 生成了 28 个在大圆内部的圆 生成了 10 个在大圆内部的圆且不与中圆有交集的圆

但是在产生大量的标准圆上,随机生成的总量会非常大:(可以考虑将随机圆半径减少,或者生成该页面之前,提前生成好这些标准圆相关数据:即圆心坐标和半径)

为了寻找 30 个标准圆 一共生成了 233220 个随机圆 生成了 138095 个在大圆内部的圆 生成了 40287 个在大圆内部的圆且不与中圆有交集的圆

最后给出最终成果图:

对应的log日志:

为了寻找 9 个标准圆 一共生成了 127 个随机圆 生成了 75 个在大圆内部的圆 生成了 20 个在大圆内部的圆且不与中圆有交集的圆为了寻找 12 个标准圆 一共生成了 265 个随机圆 生成了 150 个在大圆内部的圆 生成了 40 个在大圆内部的圆且不与中圆有交集的圆 为了寻找 23 个标准圆 一共生成了 5181 个随机圆 生成了 3112 个在大圆内部的圆 生成了 909 个在大圆内部的圆且不与中圆有交集的圆

源码下载:点击这里

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

(0)

相关推荐

  • iOS开发中Quartz2D控制圆形缩放和实现刷帧效果

    Quartz2D简要回顾 一.什么是Quartz2D Quartz 2D是⼀个二维绘图引擎,同时支持iOS和Mac系统 Quartz 2D能完成的工作: 绘制图形 : 线条\三角形\矩形\圆\弧等 绘制文字 绘制\生成图片(图像) 读取\生成PDF 截图\裁剪图片 自定义UI控件 二.Quartz2D在iOS开发中的价值 为了便于搭建美观的UI界面,iOS提供了UIKit框架,⾥⾯有各种各样的UI控件 UILabel:显⽰文字 UIImageView:显示图片 UIButton:同时显示图片和⽂

  • 浅谈iOS中三种生成随机数方法

    ios 有如下三种随机数方法: //第一种 srand((unsigned)time(0)); //不加这句每次产生的随机数不变 int i = rand() % 5; //第二种 srandom(time(0)); int i = random() % 5; //第三种 int i = arc4random() % 5 ; 注: ① rand()和random()实际并不是一个真正的伪随机数发生器,在使用之前需要先初始化随机种子,否则每次生成的随机数一样. ② arc4random() 是一个

  • iOS实现带文字的圆形头像效果

    下面就来实现一下这种效果   圆形头像的绘制 先来看一下效果图 分析一下: 1.首先是需要画带有背景色的圆形头像 2.然后是需要画文字 3.文字是截取的字符串的一部分 4.不同的字符串,圆形的背景色是不一样的 5.对于中英文同样处理,英文的一个字符和中文的一个汉字同样算作一个字符 6.文字总是居中显示 好 有了这样几点 我们就可以开始画图了 看一下最终实现的效果图 首先 ,我们需要自定义一个view当做自定义头像,在view的drawRect方法中进行图像的绘制 @interface Round

  • IOS使用progssview仿滴滴打车圆形计时

    实现类似在微信中使用的滴滴打车的progressview,实现效果如图 // // CCProgressView.h // HurricaneConsumer // // Created by wangcong on 15-3-25. // Copyright (c) 2015年 WangCong. All rights reserved. // #import <UIKit/UIKit.h> #import <QuartzCore/QuartzCore.h> /** * 动画开始

  • IOS实现圆形图片效果的两种方法

    先来看看效果图 ↓ 这个显示效果的做法有很多: 方法一: 使用两张图片, 作为边框的背景图片和中间的图片,然后使用imageView的cornerRadius来做圆, 具体代码如下: backImageView.layer.cornerRadius = backImageView.frame.size.width / 2; backImageView.layer.masksToBounds = YES; frontImageView.layer.cornerRadius = frontImage

  • iOS如何裁剪圆形头像

    本文实例为大家介绍了iOS裁剪圆形头像的详细代码,供大家参考,具体内容如下 - (void)viewDidLoad { [super viewDidLoad]; //加载图片 UIImage *image = [UIImage imageNamed:@"菲哥"]; //获取图片尺寸 CGSize size = image.size; //开启位图上下文 UIGraphicsBeginImageContextWithOptions(size, NO, 0); //创建圆形路径 UIBez

  • 利用iOS绘制图片生成随机验证码示例代码

    先来看看效果图 实现方法 .h文件 @property (nonatomic, retain) NSArray *changeArray; @property (nonatomic, retain) NSMutableString *changeString; @property (nonatomic, retain) UILabel *codeLabel; -(void)changeCode; @end .m文件 @synthesize changeArray = _changeArray;

  • iOS开发之随机生成两圆之间的标准圆

    前言 相信很多社交产品中,肯定会存在寻找附近人或者附近商家的需求,类似下图,在大圆和小圆之间(橘色区域)生成一系列的随机圆,并且所有随机圆之间也不能有交集,我暂且称这种圆为标准圆. 关于这样的需要以前在做项目中有同事做过,虽然可以实现了上面的效果图,但是坐标及半径都是写死,从写死的数据随机取值,看上去是满足了,但是对于用户来说多次使用该功能时,肯定有一定的视觉疲倦,且写死的一些数据真的不好写,如果大圆或者小圆半径变化了,或者需要更多的标准圆,那怎么办呢?一脸懵逼???? 实现思路 思路一: 对于

  • iOS开发实现随机图片验证码封装

    在 iOS 开发中,为了防止短信验证码的恶意获取,注册时需要图片验证,比如某共享单车 APP 在注册时就用了图片验证码,如下图: 图片验证码封装思路: 第一眼看到图片验证码,可能会觉得图片验证码是由 UIImage 实现的,但事实上明显不是,这里简单说下图片验证码封装思路. 首先要有一个数组,里面包含 1-9.a-z 这些字符 在 UIView 上显示这些字符 同时在 UIView 上绘制干扰线 效果图 图片验证码效果图 用法 _testView = [[NNValidationView all

  • 详解IOS开发中生成推送的pem文件

    详解IOS开发中生成推送的pem文件 具体步骤如下: 首先,需要一个pem的证书,该证书需要与开发时签名用的一致. 具体生成pem证书方法如下: 1. 登录到 iPhone Developer Connection Portal(http://developer.apple.com/iphone/manage/overview/index.action )并点击 App IDs 2. 创建一个不使用通配符的 App ID .通配符 ID 不能用于推送通知服务.例如,  com.itotem.ip

  • iOS开发生成二维码图片(附中间带有小图标二维码)

    生成二维码图片也是项目中常用到的,二维码的扫描Git上有很多好用的,这里主要说下二维码的生成 1.普通二维码 1.1 方法 /** 生成二维码 QRStering:字符串 imageFloat:二维码图片大小 */ + (UIImage *)createQRCodeWithString:(NSString *)QRStering withImgSize:(CGFloat)imageFloat; 1.2 方法实现 /** 生成二维码 QRStering:字符串 imageFloat:二维码图片大小

  • IOS开发之判断两个数组中数据是否相同实例详解

    IOS开发之判断两个数组中数据是否相同实例详解 前言: 工作中遇到的问题,这里记录下,也许能帮助到大家 实例代码: NSArray *array1 = [NSArray arrayWithObjects:@"a", @"b", @"c", nil nil]; NSArray *array2 = [NSArray arrayWithObjects:@"b", @"a", @"c", nil

  • C#随机生成不重复字符串的两个不错方法

    今天整理以前一个项目源码,发现两个随机生成不重复字符串的方法,觉得用起来挺方便的,在此贴出来,方便以后查阅. 方法一:随机生成不重复数字字符串 复制代码 代码如下: private int rep=0; /// <summary> /// 生成随机数字字符串 /// </summary> /// <param name="codeCount">待生成的位数</param> /// <returns>生成的数字字符串</r

  • ASP.NET生成两个日期范围内随机时间的实现方法

    本文实例讲述了ASP.NET生成两个日期范围内随机时间的实现方法.分享给大家供大家参考.具体方法分析如下: 想网上找个生成随机天数的方法找不到,后面只得自己写了,贴给大家方便使用 思路:算两个日期的相差天数,然后在0到相差天数的范围内生成随机数,再用结束时间的天数部分减去这个随机数,代码: 复制代码 代码如下: /// <summary> /// (在两个时间范围内)生成随机日期 /// </summary> /// <param name="startime&qu

  • JS简单生成两个数字之间随机数的方法

    本文实例讲述了JS简单生成两个数字之间随机数的方法.分享给大家供大家参考,具体如下: 运行效果截图如下: 完整代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xh

  • 详解IOS开发中图片上传时两种图片压缩方式的比较

    IOS 图片上传时两种图片压缩方式的比较 上传图片不全面的想法:把图片保存到本地,然后把图片的路径上传到服务器,最后又由服务器把路径返回,这种方式不具有扩展性,如果用户换了手机,那么新手机的沙盒中就没有服务器返回的图片路径了,此时就无法获取之前已经上传了的头像了,在项目中明显的不可行. 上传图片的正确方式:上传头像到服务器一般是将图片NSData上传到服务器,服务器返回一个图片NSString地址,之后再将NSString的路径转为url并通过url请求去更新用户头像(用户头像此时更新的便是NS

  • iOS开发系列--详细介绍数据存取

    概览 在iOS开发中数据存储的方式可以归纳为两类:一类是存储为文件,另一类是存储到数据库.例如前面IOS开发系列-Objective-C之Foundation框架的文章中提到归档.plist文件存储,包括偏好设置其本质都是存储为文件,只是说归档或者plist文件存储可以选择保存到沙盒中,而偏好设置系统已经规定只能保存到沙盒的Library/Preferences目录.当然,文件存储并不作为本文的重点内容.本文重点还是说数据库存储,做过数据库开发的朋友应该知道,可以通过SQL直接访问数据库,也可以

随机推荐