Esempio n. 1
0
polygon_t* polygon_star(point_t* x0, point_t* points, int num_points)
{
  ASSERT(num_points > 2);
  ASSERT(all_points_are_coplanar(points, num_points));

  // Find the plane of the polygon.
  vector_t normal;
  compute_normal(points, num_points, &normal);
  point_t xp;
  compute_centroid(points, num_points, &xp);
  sp_func_t* plane = plane_new(&normal, &xp);

  // Find the angles of the points within the plane, and sort the points 
  // by this angle.
  point2_t pts[num_points];
  for (int i = 0; i < num_points; ++i)
    plane_project(plane, &points[i], &pts[i]);
  point2_t xc;
  plane_project(plane, x0, &xc);
  polygon2_t* poly2 = polygon2_star(&xc, pts, num_points);

  // Read off the vertex ordering from the planar polygon. 
  ASSERT(polygon2_num_vertices(poly2) == num_points);
  int* ordering = polygon2_ordering(poly2);

  // Create our polygon with the given ordering.
  polygon_t* poly = polygon_new_with_ordering(points, ordering, num_points);

  // Clean up.
  poly2 = NULL;
  plane = NULL;

  return poly;
}
Esempio n. 2
0
polygon_t* polygon_giftwrap(point_t* points, int num_points)
{
  ASSERT(num_points > 2);
  ASSERT(all_points_are_coplanar(points, num_points));

  // Find the plane of the polygon.
  vector_t normal;
  compute_normal(points, num_points, &normal);
  point_t x0;
  compute_centroid(points, num_points, &x0);
  sp_func_t* plane = plane_new(&normal, &x0);

  // Do the gift-wrapping in 2D.
  point2_t pts[num_points];
  for (int i = 0; i < num_points; ++i)
    plane_project(plane, &points[i], &pts[i]);
  polygon2_t* poly2 = polygon2_giftwrap(pts, num_points);

#if 0
  // Re-embed the resulting vertices in 3D.
  int num_vertices = polygon2_num_vertices(poly2);
  point_t vertices[num_vertices];
  int pos = 0, offset = 0;
  point2_t* vtx;
  while (polygon2_next_vertex(poly2, &pos, &vtx))
    plane_embed(plane, vtx, &vertices[offset++]);
#endif

  // Read off the vertex ordering from the planar polygon. Note that 
  // not all of the vertices will be used in general.
  int num_p2_points = polygon2_num_vertices(poly2);
  int* ordering = polygon2_ordering(poly2);

  // Create our polygon with the given ordering.
  polygon_t* poly = NULL;
  if (num_p2_points < num_points)
  {
    point_t p2_points[num_p2_points];
    for (int i = 0; i < num_p2_points; ++i)
      point_copy(&p2_points[i], &points[ordering[i]]);
    poly = polygon_new(p2_points, num_p2_points);
  }
  else
    poly = polygon_new_with_ordering(points, ordering, num_points);

  // Clean up.
  poly2 = NULL;
  plane = NULL;

  return poly;
}
Esempio n. 3
0
collision sphere_collide_ctri(sphere s, vec3 v, ctri ct) {
  
  if (!sphere_swept_intersects_plane(s, v, plane_new(ct.a, ct.norm))) {
    return collision_none();
  }
  
  collision col = sphere_collide_face(s, v, ct);
  
  if (col.collided) { return col; }
  
  col = collision_merge(col, sphere_collide_edge(s, v, ct.a, ct.b));
  col = collision_merge(col, sphere_collide_edge(s, v, ct.b, ct.c));
  col = collision_merge(col, sphere_collide_edge(s, v, ct.c, ct.a));
  col = collision_merge(col, sphere_collide_point(s, v, ct.a));
  col = collision_merge(col, sphere_collide_point(s, v, ct.b));
  col = collision_merge(col, sphere_collide_point(s, v, ct.c));
  
  return col;
  
}
Esempio n. 4
0
collision point_collide_ctri(vec3 p, vec3 v, ctri ct) {

  if (!point_swept_intersects_plane(p, v, plane_new(ct.a, ct.norm))) {
    return collision_none();
  }
  
  collision col = point_collide_face(p, v, ct);
  
  if (col.collided) { return col; }
  
  col = collision_merge(col, point_collide_edge(p, v, ct.a, ct.b));
  col = collision_merge(col, point_collide_edge(p, v, ct.b, ct.c));
  col = collision_merge(col, point_collide_edge(p, v, ct.c, ct.a));
  col = collision_merge(col, point_collide_point(p, v, ct.a));
  col = collision_merge(col, point_collide_point(p, v, ct.b));
  col = collision_merge(col, point_collide_point(p, v, ct.c));
  
  return col;

}
Esempio n. 5
0
sp_func_t* rect_prism_new(point_t* x0, 
                          real_t L1, real_t L2, real_t L3,
                          real_t alpha, real_t beta, real_t gamma)
{
  ASSERT(L1 > 0.0);
  ASSERT(L2 > 0.0);
  ASSERT(L3 > 0.0);

  // FOR NOW, we disable Euler angles.
  if ((alpha != 0.0) || (beta != 0.0) || (gamma != 0.0))
    polymec_error("rect_prism_new: Euler angles not yet implemented!");

  // Set the 6 bounding planes.
  vector_t n;
  point_t x;
  sp_func_t* planes[6];

  // "-x" direction
  n.x = 1.0, n.y = 0.0, n.z = 0.0;
  x.x = x0->x - 0.5*L1, x.y = x0->y, x.z = x0->z;
  planes[0] = plane_new(&n, &x);

  // "+x" direction
  n.x = -1.0, n.y = 0.0, n.z = 0.0;
  x.x = x0->x + 0.5*L1, x.y = x0->y, x.z = x0->z;
  planes[1] = plane_new(&n, &x);

  // "-y" direction
  n.x = 0.0, n.y = 1.0, n.z = 0.0;
  x.x = x0->x, x.y = x0->y - 0.5*L2, x.z = x0->z;
  planes[2] = plane_new(&n, &x);

  // "+y" direction
  n.x = 0.0, n.y = -1.0, n.z = 0.0;
  x.x = x0->x, x.y = x0->y + 0.5*L2, x.z = x0->z;
  planes[3] = plane_new(&n, &x);

  // "-z" direction
  n.x = 0.0, n.y = 0.0, n.z = 1.0;
  x.x = x0->x, x.y = x0->y, x.z = x0->z - 0.5*L3;
  planes[4] = plane_new(&n, &x);

  // "+y" direction
  n.x = 0.0, n.y = 0.0, n.z = -1.0;
  x.x = x0->x, x.y = x0->y, x.z = x0->z + 0.5*L3;
  planes[5] = plane_new(&n, &x);

  rect_prism_t* p = polymec_malloc(sizeof(rect_prism_t));
  p->prism = intersection_new(planes, 6);

  // Set up the spatial function.
  sp_func_vtable vtable = {.eval = prism_eval, 
                           .eval_deriv = prism_eval_deriv, 
                           .has_deriv = prism_has_deriv, 
                           .dtor = prism_free};
  char str[1024];
  snprintf(str, 1024, "Rectangular prism (x0 = (%g, %g, %g), L1 = %g, L2 = %g, L3 = %g,"
                      " alpha = %g, beta = %g, gamma = %g)", 
                      x0->x, x0->y, x0->z, L1, L2, L3, alpha, beta, gamma);
  return sp_func_new(str, p, vtable, SP_FUNC_INHOMOGENEOUS, 1);
}
Esempio n. 6
0
static void polygon_compute_plane(polygon_t* poly)
{
  compute_normal(poly->vertices, poly->num_vertices, &poly->normal);
  compute_centroid(poly->vertices, poly->num_vertices, &poly->x0);
  poly->plane = plane_new(&poly->normal, &poly->x0);
}
Esempio n. 7
0
gint load_planes(gchar *filename, struct model_pak *data)
{
gint h, k, l, num_tokens;
gint cflag=FALSE, sflag=FALSE, gflag=FALSE;
gdouble m[3];
gchar **buff;
GSList *list, *new_planes;
struct plane_pak *plane=NULL;
struct shift_pak *shift=NULL;
FILE *fp;

fp = fopen(filename, "rt");
if (!fp)
  return(1);

/* get next line */
new_planes = NULL;
for (;;)
  {
  buff = get_tokenized_line(fp, &num_tokens);
  if (!buff)
    break;

/* NB: only update space/cell etc. data if this call did */
/* not originate from an import planes call */
  if (data->id == MORPH)
    {
/* cell parameters */
    if (g_ascii_strncasecmp(*buff,"cell",4) == 0)
      {
      if (num_tokens >= 7)
        {
        cflag=TRUE;
        data->pbc[0] = str_to_float(*(buff+1));
        data->pbc[1] = str_to_float(*(buff+2));
        data->pbc[2] = str_to_float(*(buff+3));
        data->pbc[3] = PI*str_to_float(*(buff+4))/180.0;
        data->pbc[4] = PI*str_to_float(*(buff+5))/180.0;
        data->pbc[5] = PI*str_to_float(*(buff+6))/180.0;
/* compute direct & reciprocal lattices */
/* NB: enables fn_make_plane() to correctly compute Dhkl */
        matrix_lattice_init(data);
        }
      else
        printf("load_planes() error: bad cell line.\n");
      }

/* space group */
    if (g_ascii_strncasecmp(*buff,"space",5) == 0)
      {
      if (num_tokens > 1)
        {
      sflag=TRUE;
      data->sginfo.spacename = g_strjoinv(" ", buff+1);
      data->sginfo.spacenum = 0;
        }
      }

/* default morphology type */
    if (g_ascii_strncasecmp(*buff, "morph", 5) == 0)
      {
      if (num_tokens >= 3)
        {
        if (g_ascii_strncasecmp(*(buff+1), "unrelaxed", 9) == 0)
          {
          if (g_ascii_strncasecmp(*(buff+2), "equil", 5) == 0)
            data->morph_type = EQUIL_UN;
          if (g_ascii_strncasecmp(*(buff+2), "growth", 6) == 0)
            data->morph_type = GROWTH_UN;
          }
  
        if (g_ascii_strncasecmp(*(buff+1), "relaxed", 7) == 0)
          {
          if (g_ascii_strncasecmp(*(buff+2), "equil", 5) == 0)
            data->morph_type = EQUIL_RE;
          if (g_ascii_strncasecmp(*(buff+2), "growth", 6) == 0)
            data->morph_type = GROWTH_RE;
          }
        }
      else
        printf("load_planes() error: bad type line.\n");
      }
    }

/* process miller line */
  if (g_ascii_strncasecmp(*buff,"miller",6) == 0)
    {
/* init space group (latmat? - if so, remove the make_latmat() in cell parse) */
    if (cflag && sflag)
      {
      if (!gflag)
        {
        if (space_lookup(data))
          printf("Error in space group lookup.\n");
        gflag = TRUE;
        }
      }
    else
      {
      if (data->id == MORPH)
        {
        printf("load_planes() error: miller encountered before space or cell.\n");
        return(2);
        }
      }

    if (num_tokens >= 4)
      {
      h = (gint) str_to_float(*(buff+1));
      k = (gint) str_to_float(*(buff+2));
      l = (gint) str_to_float(*(buff+3));
#if DEBUG_LOAD_PLANES
printf("read plane: %d %d %d\n", h, k, l);
#endif
      VEC3SET(m, h, k, l);
/* FIXME - signature change */
/*
      plane = plane_find(m, data);
*/

      if (!plane)
        {
        plane = plane_new(m, data);
        if (plane)
          new_planes = g_slist_prepend(new_planes, plane);
        }
      }
    }

/* potential data */
  if (num_tokens >= 8 && plane)
    {
/* NB: use create_shift(), as it sets some important defaults */
    shift = shift_new(0.0);
    if (shift)
      {
      shift->shift = str_to_float(*(buff+0));
      shift->region[0] = str_to_float(*(buff+1));
      shift->region[1] = str_to_float(*(buff+2));
      shift->esurf[0] = str_to_float(*(buff+3));
      shift->eatt[0] = str_to_float(*(buff+4));
      shift->esurf[1] = str_to_float(*(buff+5));
      shift->eatt[1] = str_to_float(*(buff+6));
      shift->gnorm = str_to_float(*(buff+7));
#if DEBUG_LOAD_PLANES
printf("adding shift: %f\n", shift->shift);
#endif
/* append to preserve order (eg import on existing plane set) */
      plane->shifts = g_slist_append(plane->shifts, shift);
      }
    }
  g_strfreev(buff);
  }
data->planes = g_slist_concat(data->planes, g_slist_reverse(new_planes));

/* compute dhkl's for the plane's list */
for (list=data->planes ; list ; list=g_slist_next(list))
  {
  plane = list->data;

/* create default shift if none found */
  if (!plane->shifts)
    {
    shift = shift_new(0.0);
    if (shift)
      plane->shifts = g_slist_append(plane->shifts, shift);
    }
/* get best energy for the plane */
/* FIXME - signature changed */
/*
  update_plane_energy(plane, data);
*/
  }

/* compute symmetry related faces */
/* FIXME - new surface rewrite */
/*
surf_symmetry_generate(data);
*/

fclose(fp);
return(0);
}