static bool find_fourth_point(int num_points, const double (*points)[3], int a, int b, int c, int* p_d)
{
	double plane_normal[3];
	calculate_plane_normal(points, a, b, c, plane_normal);


	int bi = -1;
	double max_dist = 0.0;
	for (int i = 0;i<num_points;i++)
	{
		if (i == a || i == b || i == c)
			continue;

		const double* x0 = points[i];
		double dist = fabs(point_plane_distance(x0, points[a], plane_normal));
		if (dist > max_dist)
		{
			max_dist = dist;
			bi = i;
		}
	}

	*p_d = bi;
	return max_dist > TOLERANCE;
}
Example #2
0
double point3_plane_distance(const point_type * p0 , const point_type * p1 , const point_type * p2 , const point_type * x) {
  point_type n;
  point_normal_vector( &n , p0 , p1 , p2 );
  return point_plane_distance( x , &n , p0 ) / sqrt( n.x*n.x + n.y*n.y + n.z*n.z);
}
Example #3
0
DBL BicubicPatch::determine_subpatch_flatness(const ControlPoints *Patch)
{
    int i, j;
    DBL d, dist, temp1;
    Vector3d n;
    Vector3d TempV;
    Vector3d vertices[3];

    vertices[0] = (*Patch)[0][0];
    vertices[1] = (*Patch)[0][3];

    TempV = vertices[0] - vertices[1];

    temp1 = TempV.length();

    if (fabs(temp1) < EPSILON)
    {
        /*
         * Degenerate in the V direction for U = 0. This is ok if the other
         * two corners are distinct from the lower left corner - I'm sure there
         * are cases where the corners coincide and the middle has good values,
         * but that is somewhat pathalogical and won't be considered.
         */

        vertices[1] = (*Patch)[3][3];

        TempV = vertices[0] - vertices[1];

        temp1 = TempV.length();

        if (fabs(temp1) < EPSILON)
        {
            return (-1.0);
        }

        vertices[2] = (*Patch)[3][0];

        TempV = vertices[0] - vertices[1];

        temp1 = TempV.length();

        if (fabs(temp1) < EPSILON)
        {
            return (-1.0);
        }

        TempV = vertices[1] - vertices[2];

        temp1 = TempV.length();

        if (fabs(temp1) < EPSILON)
        {
            return (-1.0);
        }
    }
    else
    {
        vertices[2] = (*Patch)[3][0];

        TempV = vertices[0] - vertices[1];

        temp1 = TempV.length();

        if (fabs(temp1) < EPSILON)
        {
            vertices[2] = (*Patch)[3][3];

            TempV = vertices[0] - vertices[2];

            temp1 = TempV.length();

            if (fabs(temp1) < EPSILON)
            {
                return (-1.0);
            }

            TempV = vertices[1] - vertices[2];

            temp1 = TempV.length();

            if (fabs(temp1) < EPSILON)
            {
                return (-1.0);
            }
        }
        else
        {
            TempV = vertices[1] - vertices[2];

            temp1 = TempV.length();

            if (fabs(temp1) < EPSILON)
            {
                return (-1.0);
            }
        }
    }

    /*
     * Now that a good set of candidate points has been found,
     * find the plane equations for the patch.
     */

    if (subpatch_normal(vertices[0], vertices[1], vertices[2], n, &d))
    {
        /*
         * Step through all vertices and see what the maximum
         * distance from the plane happens to be.
         */

        dist = 0.0;

        for (i = 0; i < 4; i++)
        {
            for (j = 0; j < 4; j++)
            {
                temp1 = fabs(point_plane_distance((*Patch)[i][j], n, d));

                if (temp1 > dist)
                {
                    dist = temp1;
                }
            }
        }

        return (dist);
    }
    else
    {
/*
        Debug_Info("Subpatch normal failed in determine_subpatch_flatness\n");
*/

        return (-1.0);
    }
}
int get_convex_hull(int num_points, const double (*points)[3], int num_expected_facets, convexhull_t* ch, int8_t simplex[][3])
{
	assert(num_points == 7 || num_points == 13 || num_points == 15);

	int ret = 0;
	int num_prev = ch->num_prev;
	ch->num_prev = num_points;
	if (!ch->ok || 0)
	{
		ret = initialize_convex_hull(num_points, points, ch->facets, ch->plane_normal, ch->processed, ch->initial_vertices, ch->barycentre);
		if (ret != 0)
			return ret;

		ch->num_facets = 4;
		num_prev = 0;
	}

	for (int i = num_prev;i<num_points;i++)
	{
		if (ch->processed[i])
			continue;
		ch->processed[i] = true;

		int num_to_add = 0;
		int8_t to_add[MAXF][3];
		int8_t edge_visible[15][15];
		memset(edge_visible, 0, sizeof(int8_t) * 15 * 15);
		for (int j = 0;j<ch->num_facets;j++)
		{
			int a = ch->facets[j][0];
			int b = ch->facets[j][1];
			int c = ch->facets[j][2];

			int u = 0, v = 0, w = 0;

			double distance = point_plane_distance(points[i], points[a], ch->plane_normal[j]);
			bool vis = distance > TOLERANCE;
			if (vis)
			{
				u = edge_visible[a][b] |= VISIBLE;
				edge_visible[b][a] |= VISIBLE;

				v = edge_visible[b][c] |= VISIBLE;
				edge_visible[c][b] |= VISIBLE;

				w = edge_visible[c][a] |= VISIBLE;
				edge_visible[a][c] |= VISIBLE;

				memcpy(ch->facets[j], ch->facets[ch->num_facets-1], 3 * sizeof(int8_t));
				memcpy(ch->plane_normal[j], ch->plane_normal[ch->num_facets-1], 3 * sizeof(double));
				ch->num_facets--;
				j--;
			}
			else
			{
				u = edge_visible[a][b] |= INVISIBLE;
				edge_visible[b][a] |= INVISIBLE;

				v = edge_visible[b][c] |= INVISIBLE;
				edge_visible[c][b] |= INVISIBLE;

				w = edge_visible[c][a] |= INVISIBLE;
				edge_visible[a][c] |= INVISIBLE;
			}

			if (u == BOTH)
			{
				to_add[num_to_add][0] = i;
				to_add[num_to_add][1] = a;
				to_add[num_to_add][2] = b;
				num_to_add++;
			}

			if (v == BOTH)
			{
				to_add[num_to_add][0] = i;
				to_add[num_to_add][1] = b;
				to_add[num_to_add][2] = c;
				num_to_add++;
			}

			if (w == BOTH)
			{
				to_add[num_to_add][0] = i;
				to_add[num_to_add][1] = c;
				to_add[num_to_add][2] = a;
				num_to_add++;
			}
		}

		for (int j = 0;j<num_to_add;j++)
		{
			if (ch->num_facets >= MAXF)
				return -4;

			add_facet(points, to_add[j][0], to_add[j][1], to_add[j][2], ch->facets[ch->num_facets], ch->plane_normal[ch->num_facets], ch->barycentre); ch->num_facets++;
		}
	}


	if (ch->num_facets != num_expected_facets)
		return -5;			//incorrect number of facets in convex hull

	for (int i=0;i<ch->num_facets;i++)
	{
		int a = ch->facets[i][0];
		int b = ch->facets[i][1];
		int c = ch->facets[i][2];
		if (a == 0 || b == 0 || c == 0)
			return -6;		//central atom contained in convex hull

		simplex[i][0] = a - 1;
		simplex[i][1] = b - 1;
		simplex[i][2] = c - 1;
	}

	return ret;
}
static bool visible(const double* w, const double* plane_point, const double* plane_normal)
{
	return point_plane_distance(w, plane_point, plane_normal) > 0;
}
Example #6
0
static DBL determine_subpatch_flatness(VECTOR (*Patch)[4][4])
{
  int i, j;
  DBL d, dist, temp1;
  VECTOR n, TempV;
  VECTOR vertices[4];

  Assign_Vector(vertices[0], (*Patch)[0][0]);
  Assign_Vector(vertices[1], (*Patch)[0][3]);

  VSub(TempV, vertices[0], vertices[1]);

  VLength(temp1, TempV);

  if (fabs(temp1) < EPSILON)
  {
    /*
     * Degenerate in the V direction for U = 0. This is ok if the other
     * two corners are distinct from the lower left corner - I'm sure there
     * are cases where the corners coincide and the middle has good values,
     * but that is somewhat pathalogical and won't be considered.
     */

    Assign_Vector(vertices[1], (*Patch)[3][3]);

    VSub(TempV, vertices[0], vertices[1]);

    VLength(temp1, TempV);

    if (fabs(temp1) < EPSILON)
    {
      return (-1.0);
    }

    Assign_Vector(vertices[2], (*Patch)[3][0]);

    VSub(TempV, vertices[0], vertices[1]);

    VLength(temp1, TempV);

    if (fabs(temp1) < EPSILON)
    {
      return (-1.0);
    }

    VSub(TempV, vertices[1], vertices[2]);

    VLength(temp1, TempV);

    if (fabs(temp1) < EPSILON)
    {
      return (-1.0);
    }
  }
  else
  {
    Assign_Vector(vertices[2], (*Patch)[3][0]);

    VSub(TempV, vertices[0], vertices[1]);

    VLength(temp1, TempV);

    if (fabs(temp1) < EPSILON)
    {
      Assign_Vector(vertices[2], (*Patch)[3][3]);

      VSub(TempV, vertices[0], vertices[2]);

      VLength(temp1, TempV);

      if (fabs(temp1) < EPSILON)
      {
        return (-1.0);
      }

      VSub(TempV, vertices[1], vertices[2]);

      VLength(temp1, TempV);

      if (fabs(temp1) < EPSILON)
      {
        return (-1.0);
      }
    }
    else
    {
      VSub(TempV, vertices[1], vertices[2]);

      VLength(temp1, TempV);

      if (fabs(temp1) < EPSILON)
      {
        return (-1.0);
      }
    }
  }

  /*
   * Now that a good set of candidate points has been found,
   * find the plane equations for the patch.
   */

  if (subpatch_normal(vertices[0], vertices[1], vertices[2], n, &d))
  {
    /*
     * Step through all vertices and see what the maximum
     * distance from the plane happens to be.
     */

    dist = 0.0;

    for (i = 0; i < 4; i++)
    {
      for (j = 0; j < 4; j++)
      {
        temp1 = fabs(point_plane_distance(((*Patch)[i][j]), n, &d));

        if (temp1 > dist)
        {
          dist = temp1;
        }
      }
    }

    return (dist);
  }
  else
  {
/*
    Debug_Info("Subpatch normal failed in determine_subpatch_flatness\n");
*/

    return (-1.0);
  }
}