q
//气泡排布算法
class BubbleCalculation {
public:
double leftSpace;/*左边空隙*/
BubbleCalculation* right;
BubbleCalculation* left;
ObjectData* data;
BubbleCalculation();
~BubbleCalculation(); void add(ObjectData* data);
/*左偏移 ture偏移成功-false失败*/
bool offsetLeft(double d);
};
//class BubbleCalculation 气泡标注排布算法
BubbleCalculation::~BubbleCalculation() {
if (this->right != NULL)delete this->right;
this->left = NULL;
this->right = NULL; }
BubbleCalculation::BubbleCalculation() {
this->left = NULL;
this->right = NULL;
this->data = NULL;
this->leftSpace = 0;
}
void BubbleCalculation::add(ObjectData* data) {
if (this->right == NULL) {
BubbleCalculation* bb = new BubbleCalculation();
/*下一个球标的x坐标*/
double x1 = data->bublePos[0];
/*当前球标的x坐标*/
double x2 = this->data == NULL ? 0 : this->data->bublePos[0];
/*判断下一个球标和当前球标是否干涉 */
double temp = x1 - x2 - data->bubbleSize;
if (temp < 0) {/*干涉*/
if (fabsf(temp) < data->bubbleSize) {/*干涉距离小于球标直径*/
/*当前球标往左移动干涉距离的一半*/
/*如果成功,下一个球标往右移动干涉距离的一半or*往右移动一个干涉距离*/
data->bublePos[0]+=this->offsetLeft(temp / 2)? fabsf(temp) / 2: fabsf(temp);
temp = 0;/*干涉归零*/
}
else {/*干涉距离大于等于球标直径*/
/*当前球标往左移动干球标直径的一半*/
data->bublePos[0]=this->offsetLeft(-data->bubbleSize / 2)? x2 + data->bubbleSize / 2 : x2 + data->bubbleSize;
temp = 0;/*干涉归零*/
}
}
bb->leftSpace = temp;
bb->data = data;
bb->left = this;
this->right = bb;
return;
}
this->right->add(data); }
bool BubbleCalculation::offsetLeft(double d) {
if (d < 0) {
if (this->data != NULL) {/*当前有球标数据*/
/*左移自检*/
double tempX= this->data->bublePos[0] + d;
if (tempX < ObjectData::bubbleMinX+ this->data->bubbleSize/2) return false;/*出界*/
/*左边空隙减少*/
double tmep = this->leftSpace + d;
/*左移他检*/
if (!this->left->offsetLeft(tmep))return false;
/*左边间隙为负-归零*/
this->leftSpace = tmep < 0 ? 0 : tmep;
/*球标左移*/
this->data->bublePos[0] = tempX;
}
}
return true; }