Fuzzy libray for embedded targets developed by zerokol. Read more on: http://zerokol.com/product/51e93616e84c5571b7000018/2/en edit by Bruno Alfano - corrected deallocation of FuzzyOutput

Fuzzy library by Zerokol. Read more on: http://zerokol.com/product/51e93616e84c5571b7000018/2/en

edit by Bruno Alfano - corrected deallocation bug for FuzzyOutput

Committer:
astaff15
Date:
Wed Jun 24 06:30:39 2015 +0000
Revision:
0:66cd67db4f1b
eFLL - June 2015

Who changed what in which revision?

UserRevisionLine numberNew contents of line
astaff15 0:66cd67db4f1b 1 /*
astaff15 0:66cd67db4f1b 2 * Robotic Research Group (RRG)
astaff15 0:66cd67db4f1b 3 * State University of Piaui (UESPI), Brazil - Piauí - Teresina
astaff15 0:66cd67db4f1b 4 *
astaff15 0:66cd67db4f1b 5 * FuzzyComposition.cpp
astaff15 0:66cd67db4f1b 6 *
astaff15 0:66cd67db4f1b 7 * Author: Msc. Marvin Lemos <marvinlemos@gmail.com>
astaff15 0:66cd67db4f1b 8 * AJ Alves <aj.alves@zerokol.com>
astaff15 0:66cd67db4f1b 9 * Co authors: Douglas S. Kridi <douglaskridi@gmail.com>
astaff15 0:66cd67db4f1b 10 * Kannya Leal <kannyal@hotmail.com>
astaff15 0:66cd67db4f1b 11 */
astaff15 0:66cd67db4f1b 12 #include "FuzzyComposition.h"
astaff15 0:66cd67db4f1b 13 #include <math.h>
astaff15 0:66cd67db4f1b 14
astaff15 0:66cd67db4f1b 15 // CONSTRUTORES
astaff15 0:66cd67db4f1b 16 FuzzyComposition::FuzzyComposition(){
astaff15 0:66cd67db4f1b 17 this->pointsCursor = NULL;
astaff15 0:66cd67db4f1b 18 this->points = NULL;
astaff15 0:66cd67db4f1b 19 }
astaff15 0:66cd67db4f1b 20
astaff15 0:66cd67db4f1b 21 // DESTRUTOR
astaff15 0:66cd67db4f1b 22 FuzzyComposition::~FuzzyComposition(){
astaff15 0:66cd67db4f1b 23 this->cleanPoints(this->pointsCursor);
astaff15 0:66cd67db4f1b 24 this->cleanPoints(this->points);
astaff15 0:66cd67db4f1b 25 }
astaff15 0:66cd67db4f1b 26
astaff15 0:66cd67db4f1b 27 bool FuzzyComposition::addPoint(float point, float pertinence){
astaff15 0:66cd67db4f1b 28 pointsArray* aux;
astaff15 0:66cd67db4f1b 29 // Alocando espaço na memória
astaff15 0:66cd67db4f1b 30 if((aux = (pointsArray *) malloc(sizeof(pointsArray))) == NULL){
astaff15 0:66cd67db4f1b 31 return false;
astaff15 0:66cd67db4f1b 32 }
astaff15 0:66cd67db4f1b 33 aux->previous = NULL;
astaff15 0:66cd67db4f1b 34 aux->point = point;
astaff15 0:66cd67db4f1b 35 aux->pertinence = pertinence;
astaff15 0:66cd67db4f1b 36 aux->next = NULL;
astaff15 0:66cd67db4f1b 37
astaff15 0:66cd67db4f1b 38 if(this->points == NULL){
astaff15 0:66cd67db4f1b 39 this->points = aux;
astaff15 0:66cd67db4f1b 40 this->pointsCursor = aux;
astaff15 0:66cd67db4f1b 41 }else{
astaff15 0:66cd67db4f1b 42 aux->previous = this->pointsCursor;
astaff15 0:66cd67db4f1b 43 this->pointsCursor = aux;
astaff15 0:66cd67db4f1b 44 aux->previous->next = this->pointsCursor;
astaff15 0:66cd67db4f1b 45 }
astaff15 0:66cd67db4f1b 46 return true;
astaff15 0:66cd67db4f1b 47 }
astaff15 0:66cd67db4f1b 48
astaff15 0:66cd67db4f1b 49 bool FuzzyComposition::checkPoint(float point, float pertinence){
astaff15 0:66cd67db4f1b 50 pointsArray *aux;
astaff15 0:66cd67db4f1b 51 aux = this->pointsCursor;
astaff15 0:66cd67db4f1b 52 while(aux != NULL){
astaff15 0:66cd67db4f1b 53 if(aux->point == point && aux->pertinence == pertinence){
astaff15 0:66cd67db4f1b 54 return true;
astaff15 0:66cd67db4f1b 55 }
astaff15 0:66cd67db4f1b 56 aux = aux->previous;
astaff15 0:66cd67db4f1b 57 }
astaff15 0:66cd67db4f1b 58 return false;
astaff15 0:66cd67db4f1b 59 }
astaff15 0:66cd67db4f1b 60
astaff15 0:66cd67db4f1b 61 bool FuzzyComposition::build(){
astaff15 0:66cd67db4f1b 62 pointsArray *aux;
astaff15 0:66cd67db4f1b 63
astaff15 0:66cd67db4f1b 64 aux = this->points;
astaff15 0:66cd67db4f1b 65 while(aux != NULL){
astaff15 0:66cd67db4f1b 66 pointsArray *temp = aux;
astaff15 0:66cd67db4f1b 67 while(temp->previous != NULL){
astaff15 0:66cd67db4f1b 68 if(temp->point < temp->previous->point){
astaff15 0:66cd67db4f1b 69 break;
astaff15 0:66cd67db4f1b 70 }
astaff15 0:66cd67db4f1b 71 temp = temp->previous;
astaff15 0:66cd67db4f1b 72 }
astaff15 0:66cd67db4f1b 73 pointsArray* zPoint;
astaff15 0:66cd67db4f1b 74 if(temp != NULL){
astaff15 0:66cd67db4f1b 75 zPoint = temp;
astaff15 0:66cd67db4f1b 76 while(temp->previous != NULL){
astaff15 0:66cd67db4f1b 77 bool result = false;
astaff15 0:66cd67db4f1b 78 if(temp->previous->previous != NULL){
astaff15 0:66cd67db4f1b 79 result = rebuild(zPoint, zPoint->next, temp->previous, temp->previous->previous);
astaff15 0:66cd67db4f1b 80 }
astaff15 0:66cd67db4f1b 81 if(result == true){
astaff15 0:66cd67db4f1b 82 aux = this->points;
astaff15 0:66cd67db4f1b 83 break;
astaff15 0:66cd67db4f1b 84 }
astaff15 0:66cd67db4f1b 85 temp = temp->previous;
astaff15 0:66cd67db4f1b 86 }
astaff15 0:66cd67db4f1b 87 }
astaff15 0:66cd67db4f1b 88 aux = aux->next;
astaff15 0:66cd67db4f1b 89 }
astaff15 0:66cd67db4f1b 90 return true;
astaff15 0:66cd67db4f1b 91 }
astaff15 0:66cd67db4f1b 92
astaff15 0:66cd67db4f1b 93 float FuzzyComposition::avaliate(){
astaff15 0:66cd67db4f1b 94 pointsArray *aux;
astaff15 0:66cd67db4f1b 95 float numerator = 0.0;
astaff15 0:66cd67db4f1b 96 float denominator = 0.0;
astaff15 0:66cd67db4f1b 97
astaff15 0:66cd67db4f1b 98 aux = this->points;
astaff15 0:66cd67db4f1b 99 while(aux != NULL){
astaff15 0:66cd67db4f1b 100 if(aux->next != NULL){
astaff15 0:66cd67db4f1b 101 float area = 0.0;
astaff15 0:66cd67db4f1b 102 float middle = 0.0;
astaff15 0:66cd67db4f1b 103 if(aux->point == aux->next->point){
astaff15 0:66cd67db4f1b 104 // Se Singleton
astaff15 0:66cd67db4f1b 105 area = aux->pertinence;
astaff15 0:66cd67db4f1b 106 middle = aux->point;
astaff15 0:66cd67db4f1b 107 }else if(aux->pertinence == 0.0 || aux->next->pertinence == 0.0){
astaff15 0:66cd67db4f1b 108 // Se triangulo
astaff15 0:66cd67db4f1b 109 float pertinence;
astaff15 0:66cd67db4f1b 110 if(aux->pertinence > 0.0){
astaff15 0:66cd67db4f1b 111 pertinence = aux->pertinence;
astaff15 0:66cd67db4f1b 112 }else{
astaff15 0:66cd67db4f1b 113 pertinence = aux->next->pertinence;
astaff15 0:66cd67db4f1b 114 }
astaff15 0:66cd67db4f1b 115 area = ((aux->next->point - aux->point) * pertinence) / 2.0;
astaff15 0:66cd67db4f1b 116 middle = ((aux->next->point - aux->point) / 2.0) + aux->point;
astaff15 0:66cd67db4f1b 117 }else if((aux->pertinence > 0.0 && aux->next->pertinence > 0.0) && (aux->pertinence == aux->next->pertinence)){
astaff15 0:66cd67db4f1b 118 // Se quadrado
astaff15 0:66cd67db4f1b 119 area = (aux->next->point - aux->point) * aux->pertinence;
astaff15 0:66cd67db4f1b 120 middle = ((aux->next->point - aux->point) / 2.0) + aux->point;
astaff15 0:66cd67db4f1b 121 }else if((aux->pertinence > 0.0 && aux->next->pertinence > 0.0) && (aux->pertinence != aux->next->pertinence)){
astaff15 0:66cd67db4f1b 122 // Se trapezio
astaff15 0:66cd67db4f1b 123 area = ((aux->pertinence + aux->next->pertinence) / 2.0) * (aux->next->point - aux->point);
astaff15 0:66cd67db4f1b 124 middle = ((aux->next->point - aux->point) / 2.0) + aux->point;
astaff15 0:66cd67db4f1b 125 }
astaff15 0:66cd67db4f1b 126 numerator += middle * area;
astaff15 0:66cd67db4f1b 127 denominator += area;
astaff15 0:66cd67db4f1b 128 }
astaff15 0:66cd67db4f1b 129 aux = aux->next;
astaff15 0:66cd67db4f1b 130 }
astaff15 0:66cd67db4f1b 131
astaff15 0:66cd67db4f1b 132 if(denominator == 0.0){
astaff15 0:66cd67db4f1b 133 return 0.0;
astaff15 0:66cd67db4f1b 134 }else{
astaff15 0:66cd67db4f1b 135 return numerator / denominator;
astaff15 0:66cd67db4f1b 136 }
astaff15 0:66cd67db4f1b 137 }
astaff15 0:66cd67db4f1b 138
astaff15 0:66cd67db4f1b 139 bool FuzzyComposition::empty(){
astaff15 0:66cd67db4f1b 140 // limpando a memória
astaff15 0:66cd67db4f1b 141 this->cleanPoints(this->points);
astaff15 0:66cd67db4f1b 142 // resetando os ponteiros
astaff15 0:66cd67db4f1b 143 this->points = NULL;
astaff15 0:66cd67db4f1b 144 this->pointsCursor = NULL;
astaff15 0:66cd67db4f1b 145 return true;
astaff15 0:66cd67db4f1b 146 }
astaff15 0:66cd67db4f1b 147
astaff15 0:66cd67db4f1b 148 // MÉTODOS PRIVADOS
astaff15 0:66cd67db4f1b 149 void FuzzyComposition::cleanPoints(pointsArray* aux){
astaff15 0:66cd67db4f1b 150 if(aux != NULL){
astaff15 0:66cd67db4f1b 151 // Esvaziando a memória alocada
astaff15 0:66cd67db4f1b 152 this->cleanPoints(aux->next);
astaff15 0:66cd67db4f1b 153 free(aux);
astaff15 0:66cd67db4f1b 154 }
astaff15 0:66cd67db4f1b 155 }
astaff15 0:66cd67db4f1b 156
astaff15 0:66cd67db4f1b 157 bool FuzzyComposition::rebuild(pointsArray* aSegmentBegin, pointsArray* aSegmentEnd, pointsArray* bSegmentBegin, pointsArray* bSegmentEnd){
astaff15 0:66cd67db4f1b 158 float x1 = aSegmentBegin->point;
astaff15 0:66cd67db4f1b 159 float y1 = aSegmentBegin->pertinence;
astaff15 0:66cd67db4f1b 160 float x2 = aSegmentEnd->point;
astaff15 0:66cd67db4f1b 161 float y2 = aSegmentEnd->pertinence;
astaff15 0:66cd67db4f1b 162 float x3 = bSegmentBegin->point;
astaff15 0:66cd67db4f1b 163 float y3 = bSegmentBegin->pertinence;
astaff15 0:66cd67db4f1b 164 float x4 = bSegmentEnd->point;
astaff15 0:66cd67db4f1b 165 float y4 = bSegmentEnd->pertinence;
astaff15 0:66cd67db4f1b 166 float point, pertinence;
astaff15 0:66cd67db4f1b 167 float denom, numera, numerb;
astaff15 0:66cd67db4f1b 168 float mua, mub;
astaff15 0:66cd67db4f1b 169
astaff15 0:66cd67db4f1b 170 denom = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);
astaff15 0:66cd67db4f1b 171 numera = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3);
astaff15 0:66cd67db4f1b 172 numerb = (x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3);
astaff15 0:66cd67db4f1b 173
astaff15 0:66cd67db4f1b 174 if(denom < 0.0){
astaff15 0:66cd67db4f1b 175 denom *= -1.0;
astaff15 0:66cd67db4f1b 176 }
astaff15 0:66cd67db4f1b 177 if(numera < 0.0){
astaff15 0:66cd67db4f1b 178 numera *= -1.0;
astaff15 0:66cd67db4f1b 179 }
astaff15 0:66cd67db4f1b 180 if(numerb < 0.0){
astaff15 0:66cd67db4f1b 181 numerb *= -1.0;
astaff15 0:66cd67db4f1b 182 }
astaff15 0:66cd67db4f1b 183
astaff15 0:66cd67db4f1b 184 // Se os seguimentos forem paralelos, retornar falso
astaff15 0:66cd67db4f1b 185 if(denom < EPS){
astaff15 0:66cd67db4f1b 186 return false;
astaff15 0:66cd67db4f1b 187 }
astaff15 0:66cd67db4f1b 188
astaff15 0:66cd67db4f1b 189 // Verificar se há interseção ao longo do seguimento
astaff15 0:66cd67db4f1b 190 mua = numera / denom;
astaff15 0:66cd67db4f1b 191 mub = numerb / denom;
astaff15 0:66cd67db4f1b 192 if(mua < 0.0 || mua > 1.0 || mub < 0.0 || mub > 1.0){
astaff15 0:66cd67db4f1b 193 return false;
astaff15 0:66cd67db4f1b 194 }else{
astaff15 0:66cd67db4f1b 195 // Calculando o ponto e a pertinencia do novo elemento
astaff15 0:66cd67db4f1b 196 point = x1 + mua * (x2 - x1);
astaff15 0:66cd67db4f1b 197 pertinence = y1 + mua * (y2 - y1);
astaff15 0:66cd67db4f1b 198
astaff15 0:66cd67db4f1b 199 // Adicionando um novo ponto
astaff15 0:66cd67db4f1b 200 pointsArray* aux;
astaff15 0:66cd67db4f1b 201 // Alocando espaço na memória
astaff15 0:66cd67db4f1b 202 if((aux = (pointsArray *) malloc(sizeof(pointsArray))) == NULL){
astaff15 0:66cd67db4f1b 203 return false;
astaff15 0:66cd67db4f1b 204 }
astaff15 0:66cd67db4f1b 205
astaff15 0:66cd67db4f1b 206 aux->previous = bSegmentEnd;
astaff15 0:66cd67db4f1b 207 aux->point = point;
astaff15 0:66cd67db4f1b 208 aux->pertinence = pertinence;
astaff15 0:66cd67db4f1b 209 aux->next = aSegmentEnd;
astaff15 0:66cd67db4f1b 210
astaff15 0:66cd67db4f1b 211 bSegmentEnd->next = aux;
astaff15 0:66cd67db4f1b 212 aSegmentEnd->previous = aux;
astaff15 0:66cd67db4f1b 213
astaff15 0:66cd67db4f1b 214 float stopPoint = bSegmentBegin->point;
astaff15 0:66cd67db4f1b 215 float stopPertinence = bSegmentBegin->pertinence;
astaff15 0:66cd67db4f1b 216
astaff15 0:66cd67db4f1b 217 pointsArray* temp = aSegmentBegin;
astaff15 0:66cd67db4f1b 218 pointsArray* excl;
astaff15 0:66cd67db4f1b 219
astaff15 0:66cd67db4f1b 220 do{
astaff15 0:66cd67db4f1b 221 float pointToCompare = temp->point;
astaff15 0:66cd67db4f1b 222 float pertinenceToCompare = temp->pertinence;
astaff15 0:66cd67db4f1b 223
astaff15 0:66cd67db4f1b 224 excl = temp->previous;
astaff15 0:66cd67db4f1b 225
astaff15 0:66cd67db4f1b 226 this->rmvPoint(temp);
astaff15 0:66cd67db4f1b 227
astaff15 0:66cd67db4f1b 228 temp = excl;
astaff15 0:66cd67db4f1b 229
astaff15 0:66cd67db4f1b 230 if(stopPoint == pointToCompare && stopPertinence == pertinenceToCompare){
astaff15 0:66cd67db4f1b 231 break;
astaff15 0:66cd67db4f1b 232 }
astaff15 0:66cd67db4f1b 233 }while(temp != NULL);
astaff15 0:66cd67db4f1b 234
astaff15 0:66cd67db4f1b 235 return true;
astaff15 0:66cd67db4f1b 236 }
astaff15 0:66cd67db4f1b 237 }
astaff15 0:66cd67db4f1b 238
astaff15 0:66cd67db4f1b 239 bool FuzzyComposition::rmvPoint(pointsArray* point){
astaff15 0:66cd67db4f1b 240 if(point != NULL){
astaff15 0:66cd67db4f1b 241 free(point);
astaff15 0:66cd67db4f1b 242 }
astaff15 0:66cd67db4f1b 243 return true;
astaff15 0:66cd67db4f1b 244 }