distance.c 3.86 KB
Newer Older
Cassio Kirch's avatar
Cassio Kirch committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
#include <math.h>
#include <stdbool.h>
#include "define.h"
#include "box.h"
#include "boid.h"
#include "distance.h"

struct Distance
getDistance (const struct Boid* const boid2, const struct Boid* const boid1)
{
  struct Distance distance;
  double temp;
  
  /* Distância normal. */
  distance.module = absDistance (boid1 -> position[X],  \
                                 boid1 -> position[Y],  \
                                 boid2 -> position[X],  \
                                 boid2 -> position[Y]);
  if (distance.module < NEIGHBOR_DISTANCE)
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
  {
    distance.sine = (boid2 -> position[Y] - boid1 -> position[Y]) /     \
      distance.module;
    distance.cosine = (boid2 -> position[X] - boid1 -> position[X]) /   \
      distance.module;
    return distance;
  }
  
  else if ((isInEdge (boid1 -> boxID) == true) ||       \
           (isInEdge (boid2 -> boxID) == true))
  {
    
    /* 1o boid à esquerda. */
    temp = boid1 -> position[X] + RANGE;
    distance.module = absDistance (temp,                                \
                                   boid1 -> position[Y],                \
                                   boid2 -> position[X],                \
                                   boid2 -> position[Y]);
    if (distance.module < NEIGHBOR_DISTANCE)
    {
      distance.sine = (boid2 -> position[Y] - boid1 -> position[Y]) /   \
        distance.module;
      distance.cosine = (boid2 -> position[X] - temp) / distance.module;
      return distance;
    }
    
    /* 1o boid à direita */
    temp = boid1 -> position[X] - RANGE;
    distance.module = absDistance (temp,                                \
                                   boid1 -> position[Y],                \
                                   boid2 -> position[X],                \
                                   boid2 -> position[Y]);
    if (distance.module < NEIGHBOR_DISTANCE)
Cassio Kirch's avatar
Cassio Kirch committed
53 54 55
    {
      distance.sine = (boid2 -> position[Y] - boid1 -> position[Y]) /   \
        distance.module;
56 57 58 59 60 61 62 63 64 65 66 67 68
      distance.cosine = (boid2 -> position[X] - temp) / distance.module;
      return distance;
    }
    
    /* 1o boid abaixo */
    temp = boid1 -> position[Y] + RANGE;
    distance.module = absDistance (boid1 -> position[X],                \
                                   temp,                                \
                                   boid2 -> position[X],                \
                                   boid2 -> position[Y]);
    if (distance.module < NEIGHBOR_DISTANCE)
    {
      distance.sine = (boid2 -> position[Y] - temp) / distance.module;
Cassio Kirch's avatar
Cassio Kirch committed
69 70 71 72
      distance.cosine = (boid2 -> position[X] - boid1 -> position[X]) / \
        distance.module;
      return distance;
    }
73 74 75 76 77 78 79 80
    
    /* 1o boid acima */
    temp = boid1 -> position[Y] - RANGE;
    distance.module = absDistance (boid1 -> position[X],                \
                                   temp,                                \
                                   boid2 -> position[X],                \
                                   boid2 -> position[Y]);
    if (distance.module < NEIGHBOR_DISTANCE)
Cassio Kirch's avatar
Cassio Kirch committed
81
    {
82 83 84 85
      distance.sine = (boid2 -> position[Y] - temp) / distance.module;
      distance.cosine = (boid2 -> position[X] - boid1 -> position[X]) / \
        distance.module;
      return distance;
Cassio Kirch's avatar
Cassio Kirch committed
86
    }
87 88 89
    
    /* não vizinhos */
    else
Cassio Kirch's avatar
Cassio Kirch committed
90 91 92 93 94 95
    {
      distance.sine = 0.0;
      distance.cosine = 0.0;
      distance.module = NEIGHBOR_DISTANCE * 2.0;
      return distance;
    }
96 97 98 99 100 101 102 103 104 105
  }
  
  /* não vizinhos */
  else
  {
    distance.sine = 0.0;
    distance.cosine = 0.0;
    distance.module = NEIGHBOR_DISTANCE * 2.0;
    return distance;
  }
Cassio Kirch's avatar
Cassio Kirch committed
106 107 108 109 110 111 112 113 114 115 116 117 118
}

/* Supõe-se que a função só será chamada para boids vizinhos. */
double
getForce (const double distance)
{
  if (distance < CORE_RADIUS)
    return INFINITE_FORCE;
  //else if (distance > NEIGHBOR_DISTANCE)
  //return 0.0;
  else
    return (1.000000 - (distance / ELASTIC_DISTANCE));
}