大圆内随机生成小圆的算法

要求如下:

1. 在半径为R的大圆内,随机生成半径为r的小圆,r<R

2. 要求生成的小圆不能重叠

应用场景:

手机搜索周边的蓝牙设备,模拟雷达动画,搜到蓝牙后,位置随机显示。

代码:

本打算用递归,但憋了半天也没写出来,递归的结束条件找不到。

于是使用中间变亮作为结束条件。

bug:如果没有位置可以放了,会导致死循环,测试大约添加15个设备的时候就容易出现此bug

等待优化:

1. 效率不高

2. 算法有bug

	private void addDevice(final MbotBean bean) {
		int sideLength = (int)(Global.SCREEN_HEIGHT*(212.0f/1536.0f));
		RelativeLayout layout = new RelativeLayout(context);
		layout.setBackgroundColor(Color.RED);
		RelativeLayout.LayoutParams paramsLayout = new RelativeLayout.LayoutParams(sideLength, sideLength);
		layout.setLayoutParams(paramsLayout);
		search_relativeLayout_DeviceContainer.addView(layout);
		setLayoutAvaiablePosition(layout);

		int heightIcon = (int)(Global.SCREEN_HEIGHT*(166.0f/1536.0f));
		ImageView icon = new ImageView(context);
		icon.setImageResource(R.drawable.radar_equipment);
		icon.setBackgroundColor(Color.BLUE);
		RelativeLayout.LayoutParams paramsImageView = new RelativeLayout.LayoutParams(android.view.ViewGroup.LayoutParams.MATCH_PARENT, heightIcon);
		icon.setLayoutParams(paramsImageView);
		layout.addView(icon);

		int heightName = (int)(Global.SCREEN_HEIGHT*(40.0f/1536.0f));
		TextView name = new TextView(context);
		name.setText("Unknown");
		name.setGravity(Gravity.CENTER);
		name.setTextColor(Color.BLACK);
		name.setBackgroundColor(Color.GREEN);
		RelativeLayout.LayoutParams paramsTextView = new RelativeLayout.LayoutParams(android.view.ViewGroup.LayoutParams.MATCH_PARENT, heightName);
		paramsTextView.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
		name.setLayoutParams(paramsTextView);
		layout.addView(name);
	}

	/**
	 * 将小圆放在合适的位置,要求小圆不重叠
	 * @param layout
	 */
	private void setLayoutAvaiablePosition(RelativeLayout layout){
		int count = search_relativeLayout_DeviceContainer.getChildCount();
		//layout的center
		int centerX = Global.SCREEN_WIDTH/2;
		int centerY = (int)(Global.SCREEN_HEIGHT*(1176.0f/2.0f/1536.0f));
		int r = (int)(Global.SCREEN_HEIGHT*(212.0f/2.0f/1536.0f));
		int R = centerY;
		Random random = new Random();
		int p = random.nextInt(R-r+1); //极坐标半径[0, R-r]
		float q = (random.nextInt(2*314))/100.0f;   //极坐标角度[0,2*PI]
		//随机获取的圆的center
		int cx = (int) (centerX + p*Math.cos(q));
		int cy = (int) (centerY + p*Math.sin(q));
		int x = cx - r;
		int y = cy - r;
		Boolean result = true;
		for (int i = 0; i < count-1; i++) {
			//判断subViews和当前的DeviceLayout是否重叠
			View subView = search_relativeLayout_DeviceContainer.getChildAt(i);
			int cxSub = (int) (subView.getX()+subView.getWidth()/2);
			int cySub = (int) (subView.getY()+subView.getHeight()/2);
			int distance = (int) Math.sqrt((cx-cxSub)*(cx-cxSub)+(cy-cySub)*(cy-cySub));
			if(distance < 2*r){
				//有一个重叠,就break
				result = false;
				break;
			}
		}
		if (!result) {
			//有一个重叠,就重新计算,记得要return 
			setLayoutAvaiablePosition(layout);
			return;
		}
		//没有重叠,设置x,y
		layout.setX(x);
		layout.setY(y);
	}

  

 

posted @ 2016-03-19 14:35  MakeBetter  阅读(1706)  评论(0编辑  收藏  举报