要求如下:
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);
}