Added reading date from the GEDCOM file and storing it in individual.
[familia.git] / src / math / positions.c
index dfd8fc0252a3a768e5ff821f3cc0e19c2553613c..bf6b6067d4af11309b961d5a79f0d6b0bd42bb86 100644 (file)
@@ -1,16 +1,75 @@
 #include <stdlib.h>
+#include <math.h>
 
 #include "positions.h"
+#include "yearline.h"
 #include "storage/individual.h"
 #include "storage/family.h"
 
-struct position * familia_position_calculate_individual_position(struct familia_individual * individual)
+#include "../debug.h"
+
+#define FAMILY_AVAIL_RANGE 180
+
+struct position * calculate_individual_position(struct familia_individual * individual)
 {
-/*     TODO: Implement this function*/
-       return NULL;
+       struct position * pos = NULL;
+       struct familia_family * parents = NULL;
+       unsigned int children_no = 1;
+       int nth = 0;
+
+       parents = familia_individual_get_parents(individual);
+       if (parents == NULL) {
+               debug("TODO: Calculate position for root individual.");
+               return NULL;
+       }
+
+       nth = familia_individual_nth_child_of_family(individual, parents);
+       if (nth < 0) {
+               debug("Cannot calculate child number.");
+               return NULL;
+       }
+
+       children_no = parents->children_no;
+
+       if (children_no == 0) {
+               debug("Children number mismatch: I have child of family, " \
+                     "but parents does not have any children!");
+               return NULL;
+       }
+
+       pos = (struct position *)malloc(sizeof(struct position));
+       pos->x = 0;
+       pos->y = 0;
+       pos->z = 0;
+
+       /* If there is only one child in family, place it vertically
+        * over the family (do not change x and z). For all other
+        * calculate these positions.
+        */
+       if (children_no != 1) {
+               /* Angle by which every child is rotated. */
+               float theta = 0;
+               /* Angle by which this child will be rotated */
+               float alpha = 0;
+               theta = FAMILY_AVAIL_RANGE / children_no;
+
+               /* We subtract from FAMILY_AVAIL_RANGE (e.g. 180),
+                       * to count angle from left instead of from right.
+                       * This makes oldest children display in this order.
+               */
+               alpha = FAMILY_AVAIL_RANGE - theta * nth;
+
+               pos->x = cos(alpha);
+               pos->z = sin(alpha);
+       }
+
+       /* pos.y is a local coordinate now. */
+       pos->y = convert_date_to_height(NULL);
+
+       return pos;
 }
 
-struct position * familia_position_calculate_family_position(struct familia_family * family)
+struct position * calculate_family_position(struct familia_family * family)
 {
 /*     TODO: Implement this function*/
        return NULL;