⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 weightedring.cpp

📁 2002年
💻 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 + -