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

Revision:
0:66cd67db4f1b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FuzzyComposition.cpp	Wed Jun 24 06:30:39 2015 +0000
@@ -0,0 +1,244 @@
+/*
+ * Robotic Research Group (RRG)
+ * State University of Piaui (UESPI), Brazil - Piauí - Teresina
+ *
+ * FuzzyComposition.cpp
+ *
+ *      Author: Msc. Marvin Lemos <marvinlemos@gmail.com>
+ *              AJ Alves <aj.alves@zerokol.com>
+ *          Co authors: Douglas S. Kridi <douglaskridi@gmail.com>
+ *                      Kannya Leal <kannyal@hotmail.com>
+ */
+#include "FuzzyComposition.h"
+#include <math.h>
+
+// CONSTRUTORES
+FuzzyComposition::FuzzyComposition(){
+    this->pointsCursor  = NULL;
+    this->points        = NULL;
+}
+
+// DESTRUTOR
+FuzzyComposition::~FuzzyComposition(){
+    this->cleanPoints(this->pointsCursor);
+    this->cleanPoints(this->points);
+}
+
+bool FuzzyComposition::addPoint(float point, float pertinence){
+    pointsArray* aux;
+    // Alocando espaço na memória
+    if((aux = (pointsArray *) malloc(sizeof(pointsArray))) == NULL){
+        return false;
+    }
+    aux->previous = NULL;
+    aux->point = point;
+    aux->pertinence = pertinence;
+    aux->next = NULL;
+
+    if(this->points == NULL){
+        this->points = aux;
+        this->pointsCursor  = aux;
+    }else{
+        aux->previous = this->pointsCursor;
+        this->pointsCursor = aux;
+        aux->previous->next = this->pointsCursor;
+    }
+    return true;
+}
+
+bool FuzzyComposition::checkPoint(float point, float pertinence){
+    pointsArray *aux;
+    aux = this->pointsCursor;
+    while(aux != NULL){
+        if(aux->point == point && aux->pertinence == pertinence){
+            return true;
+        }
+        aux = aux->previous;
+    }
+    return false;
+}
+
+bool FuzzyComposition::build(){
+    pointsArray *aux;
+
+    aux = this->points;
+    while(aux != NULL){
+        pointsArray *temp = aux;
+        while(temp->previous != NULL){
+            if(temp->point < temp->previous->point){
+                break;
+            }
+            temp = temp->previous;
+        }
+        pointsArray* zPoint;
+        if(temp != NULL){
+            zPoint = temp;
+            while(temp->previous != NULL){
+                bool result = false;
+                if(temp->previous->previous != NULL){
+                    result = rebuild(zPoint, zPoint->next, temp->previous, temp->previous->previous);
+                }
+                if(result == true){
+                    aux = this->points;
+                    break;
+                }
+                temp = temp->previous;
+            }
+        }
+        aux = aux->next;
+    }
+    return true;
+}
+
+float FuzzyComposition::avaliate(){
+    pointsArray *aux;
+    float numerator     = 0.0;
+    float denominator   = 0.0;
+
+    aux = this->points;
+    while(aux != NULL){
+        if(aux->next != NULL){
+            float area = 0.0;
+            float middle = 0.0;
+            if(aux->point == aux->next->point){
+                // Se Singleton
+                area    = aux->pertinence;
+                middle  = aux->point;
+            }else if(aux->pertinence == 0.0 || aux->next->pertinence == 0.0){
+                // Se triangulo
+                float pertinence;
+                if(aux->pertinence > 0.0){
+                    pertinence = aux->pertinence;
+                }else{
+                    pertinence = aux->next->pertinence;
+                }
+                area    = ((aux->next->point - aux->point) * pertinence) / 2.0;
+                middle  = ((aux->next->point - aux->point) / 2.0) + aux->point;
+            }else if((aux->pertinence > 0.0 && aux->next->pertinence > 0.0) && (aux->pertinence == aux->next->pertinence)){
+                // Se quadrado
+                area    = (aux->next->point - aux->point) * aux->pertinence;
+                middle  = ((aux->next->point - aux->point) / 2.0) + aux->point;
+            }else if((aux->pertinence > 0.0 && aux->next->pertinence > 0.0) && (aux->pertinence != aux->next->pertinence)){
+                // Se trapezio
+                area    = ((aux->pertinence + aux->next->pertinence) / 2.0) * (aux->next->point - aux->point);
+                middle  = ((aux->next->point - aux->point) / 2.0) + aux->point;
+            }
+            numerator   += middle * area;
+            denominator += area;
+        }
+        aux = aux->next;
+    }
+
+    if(denominator == 0.0){
+        return 0.0;
+    }else{
+        return numerator / denominator;
+    }
+}
+
+bool FuzzyComposition::empty(){
+    // limpando a memória
+    this->cleanPoints(this->points);
+    // resetando os ponteiros
+    this->points = NULL;
+    this->pointsCursor = NULL;
+    return true;
+}
+
+// MÉTODOS PRIVADOS
+void FuzzyComposition::cleanPoints(pointsArray* aux){
+    if(aux != NULL){
+        // Esvaziando a memória alocada
+        this->cleanPoints(aux->next);
+        free(aux);
+    }
+}
+
+bool FuzzyComposition::rebuild(pointsArray* aSegmentBegin, pointsArray* aSegmentEnd, pointsArray* bSegmentBegin, pointsArray* bSegmentEnd){
+    float x1 = aSegmentBegin->point;
+    float y1 = aSegmentBegin->pertinence;
+    float x2 = aSegmentEnd->point;
+    float y2 = aSegmentEnd->pertinence;
+    float x3 = bSegmentBegin->point;
+    float y3 = bSegmentBegin->pertinence;
+    float x4 = bSegmentEnd->point;
+    float y4 = bSegmentEnd->pertinence;
+    float point, pertinence;
+    float denom, numera, numerb;
+    float mua, mub;
+
+    denom  = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);
+    numera = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3);
+    numerb = (x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3);
+
+    if(denom < 0.0){
+        denom *= -1.0;
+    }
+    if(numera < 0.0){
+        numera *= -1.0;
+    }
+    if(numerb < 0.0){
+        numerb *= -1.0;
+    }
+
+    // Se os seguimentos forem paralelos, retornar falso
+    if(denom < EPS){
+        return false;
+    }
+
+    // Verificar se há interseção ao longo do seguimento
+    mua = numera / denom;
+    mub = numerb / denom;
+    if(mua < 0.0 || mua > 1.0 || mub < 0.0 || mub > 1.0){
+        return false;
+    }else{
+        // Calculando o ponto e a pertinencia do novo elemento
+        point       = x1 + mua * (x2 - x1);
+        pertinence  = y1 + mua * (y2 - y1);
+
+        // Adicionando um novo ponto
+        pointsArray* aux;
+        // Alocando espaço na memória
+        if((aux = (pointsArray *) malloc(sizeof(pointsArray))) == NULL){
+            return false;
+        }
+
+        aux->previous = bSegmentEnd;
+        aux->point = point;
+        aux->pertinence = pertinence;
+        aux->next = aSegmentEnd;
+
+        bSegmentEnd->next = aux;
+        aSegmentEnd->previous = aux;
+
+        float stopPoint = bSegmentBegin->point;
+        float stopPertinence = bSegmentBegin->pertinence;
+
+        pointsArray* temp = aSegmentBegin;
+        pointsArray* excl;
+
+        do{
+            float pointToCompare = temp->point;
+            float pertinenceToCompare = temp->pertinence;
+
+            excl = temp->previous;
+
+            this->rmvPoint(temp);
+
+            temp = excl;
+
+            if(stopPoint == pointToCompare && stopPertinence == pertinenceToCompare){
+                break;
+            }
+        }while(temp != NULL);
+
+        return true;
+    }
+}
+
+bool FuzzyComposition::rmvPoint(pointsArray* point){
+    if(point != NULL){
+        free(point);
+    }
+    return true;
+}
\ No newline at end of file