📄 weightedring.cpp
字号:
#include "weightedring.h"
#include "smp_func.h"
/* -*Weighted Ring*-
*The principle here is as following :
* The space with some pos as the center is divided into a set of sectors. There is a weight
* coefficient associated with each sector that describe the extend of it's some character.
*
*Technical Implementation:
* Sectors are stored in a sorted orbicular list.
* Insert a new sector, and the intersection case can be handled automatically
* Sum up the weight along the circle
*/
/*Create a new SectorDelimiter
* a new SectorDelimiter is allocated from an array.
*/
SectorDelimiter* WeightedRing::CreateSector(){
if(curunits >= Max_Sectors) return NULL;
else return &(storage[curunits++]);
}
/*Reset ring object
* add two SectorDelimiter (-180, 180) by default. they are the basis of the ring.
*/
void WeightedRing::Reset(){
curunits = 0;
headunit = CreateSector();
tailunit = CreateSector();
tailunit->reset();
headunit->angle = -180.0f;
headunit->weight = 0;
headunit->next = tailunit;
tailunit->angle = 180.0f;
}
/*Locate the sector where angle lies in
*Return the fore delimiter of this sector
*/
SectorDelimiter* WeightedRing::Findunit(float angle){
SectorDelimiter* tmp = headunit;
while(tmp != NULL){
if(tmp->nextangle() >= angle) return tmp;
tmp = tmp->next;
}
return NULL;
}
/*Insert a new SectorDelimiter after unit
* the new sector is initialized with some extend (w)
* this is an atom function.
*/
void WeightedRing::Insertfollow(SectorDelimiter* &unit,float agl, float w){
SectorDelimiter* p = CreateSector();
if(p == NULL) return;
p->init(agl, w, unit->next);
unit->next = p;
unit = p;
}
/*Insert a new Sector from sangle to eangle with extend (weight)
* the laped section is associated with the big one of the two weights.
*/
void WeightedRing::Insertunit(float sangle,float eangle,float weight){
SectorDelimiter* sunit = Findunit(sangle);
SectorDelimiter* punit = sunit;
float w;
while(sunit->angle < eangle){
if(sunit->weight < weight){
if(sunit->angle == sangle){
w = sunit->weight;
sunit->weight = weight;
if(eangle < sunit->nextangle()){
Insertfollow(sunit, eangle, w);
}
}else if(eangle >= sunit->nextangle()){
Insertfollow(sunit, sangle, weight);
}else{
w = sunit->weight;
Insertfollow(sunit, sangle, weight);
Insertfollow(sunit, eangle, w);
}
}
sunit = sunit->next;
if(sunit == NULL) return;
sangle = sunit->angle;
}
while(punit->next != sunit && punit->next != NULL){
if(fabs(punit->weight - punit->next->weight) <= 0.01f){
punit->next = punit->next->next;
}else{
punit = punit->next;
}
}
}
/*Insert a new sector from s_angle to e_angle with some extend(weight)
*/
void WeightedRing::InsertSection(float s_angle, float e_angle, float weight){
s_angle = NormalizeAngle(s_angle);
e_angle = s_angle + NormalizeAngle(e_angle - s_angle, 0);
if(e_angle > tailunit->angle){
Insertunit(headunit->angle, NormalizeAngle(e_angle), weight);
Insertunit(s_angle, tailunit->angle, weight);
}else{
Insertunit(s_angle, e_angle, weight);
}
}
/*Insert a new sector that seizes spanangle with angle as the center line with some extend(weight)
*/
void WeightedRing::Insert(float angle,float spanangle,float weight){
if(weight<0.01f) return;
float sangle = NormalizeAngle(angle - spanangle/2);
float eangle = sangle + spanangle;
InsertSection(sangle, eangle, weight);
}
/*Sum up the extend of all the sections.
*The proportion of each sector in the sum is decided by the sector's weight
* and its scale.
*/
float WeightedRing::GetTotalWeight(){
SectorDelimiter* p = headunit;
SectorDelimiter* nextp = p->next;
float sumweight = 0,weight;
while(nextp != NULL){
weight = Getscale(p->angle, nextp->angle) * p->weight;
//weight = (nextp->angle - p->angle)/unitangle * p->weight
// * Getscale((nextp->angle + p->angle)/2);
sumweight += weight;
p = nextp;
nextp = p->next;
}
return sumweight;
}
/*this is just a default sample function of Getscale
* you should rewrite it in your inherited class.
*/
float WeightedRing::Getscale(float s_angle, float e_angle){
return (e_angle-s_angle)/360.0f;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -