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
FuzzyComposition.cpp@0:66cd67db4f1b, 2015-06-24 (annotated)
- Committer:
- astaff15
- Date:
- Wed Jun 24 06:30:39 2015 +0000
- Revision:
- 0:66cd67db4f1b
eFLL - June 2015
Who changed what in which revision?
User | Revision | Line number | New 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 | } |