0

I've been trying this for days and no solution that I've come up with has worked. I thought you clever people could give me a hand! Thank you in advance :)

I need to store the coordinates of hundreds of triangles in C. Three points for each triangle, each with its own (x y z) coordinates. It's a pain that it must be done in C however - I just can't figure out a way (let alone the best way) to do so..!

It must be possible to amend the 'list' after its creation by deleting the data for a triangle or adding a new one to the list. It is not necessary for the triangles to be in any specific order.

For example:

triangle 1 ----> point 1 ----> x
                               y
                               z
                 point 2 ----> x
                               y
                               z
                 point 3 ----> x
                               y
                               z
wohxela
  • 35
  • 6
  • Where's the pain? What type are these coordinates in? `int`? `double`? – tadman Mar 24 '21 at 12:54
  • Can you provide some more descriptions on "amend the list" part ? And, are there any range for x, y, and z? – Uduru Mar 24 '21 at 12:54
  • https://stackoverflow.com/questions/4694401/how-to-replicate-vector-in-c ? – Ramtin Nouri Mar 24 '21 at 12:54
  • If you're using C, you'll need to be more comfortable with manipulating arrays of things, shuffling data around using `memcpy()` and so on. C forces you to think about these things, there's very little in the way of abstraction there, so your job is to figure out a strategy and *write functions* that achieve a particular objective such as allocating a list of size N, appending entries, or inserting/replacing entries in the list. – tadman Mar 24 '21 at 12:55
  • @tadman yes they are doubles... :s – wohxela Mar 24 '21 at 13:11
  • @Uduru so I wouldn’t have to amend the triangles themselves- just delete a triangle or add a new triangle – wohxela Mar 24 '21 at 13:12
  • @tadman do you have an example of how I would go about doing this? It’d be much appreciated and would help me learn! – wohxela Mar 24 '21 at 13:13
  • Very loosely use `struct point { double x, y, z }` as a start, then `struct point points[N]` is a way to make an array of them. You can also `calloc()` these which gives you the ability to extend the array. – tadman Mar 24 '21 at 13:14

3 Answers3

1

You can use an array inside of a struct to create your points triangle. Here is one example:

struct triangle
{
    int id;
    int x[3], y[3], z[3]; 
};

Using this, the point 1 will use the spaces x[0], y[0] and z[0], and so on for the other points.

Another way to solve this problem is using two structs, one for the point and another one for the triangle. This way is better if you need to work directly with points several times.

struct point
{
    int id_point;
    int x, y, z; 
};

struct triangle
{
    int id_triangle;
    struct point triangle_points[3]; 
};

The ids are use to identify the triangles or points.

Rlyra
  • 86
  • 5
1

Representation of points and triangles should be relatively straightforward:

struct point { double x, y, z; };
struct triangle { struct point a, b, c; };

Representing collections of triangles is the more involved bit. If the triangles don't have to be in any particular order, you can use a simple linked list and just add new triangles to the head of the list:

struct tlist {
  struct triangle t;
  struct tlist *next;
};

int add_triangle( struct tlist **root, struct triangle t )
{
  struct tlist *node = malloc( sizeof *node );
  if ( node )
  {
    node->t = t;
    node->next = *root;
    *root = node;
  }
  return node != NULL;
}

Removing triangles from the list isn't that much harder:

void remove_triangle( struct tlist **root, struct triangle t )
{
  struct tlist *prev, *cur = *root;

  while ( cur && !triangle_match( cur->t, t ) ) // however you match triangles
  {
    prev = cur;
    cur = cur->next;
  }

  if ( cur )
  {
    if ( cur == *root )
      *root = cur->next;
    else        
      prev->next = cur->next;

    free( cur );
  }
}
    

A simple (untested) example:

int main( void )
{
  struct tlist *root = NULL;
  struct triangle t;

  /**
   * Add a bunch of triangles to the list
   */
  while ( get_next_triangle( &t ) ) // for however you get new triangle data
  {
    if ( !add_triangle( &root, t ) )
    {
      // handle error condition here
      break;
    }
  }

  /**
   * Remove a specified triangle from the list
   */
  if ( get_next_triangle( &t ) )
    remove_triangle( &root, t );

  return 0;
}

The downside of this approach is that all searches are linear; you could organize triangles for faster searching (ordering by one of the x, y, or z coordinates), but this should get you started.

John Bode
  • 119,563
  • 19
  • 122
  • 198
0

This is the start of a simple layout I began.

If I were to extend this, I would change to dynamic memory allocation (malloc), implement the ref-counting on the points, and methods to add/remove/find triangles in the master list.

#include <stdio.h>

typedef struct
{
    double x, y, z;
    int  ref_count;
    // A single point in 3-D space has 3 coordinates.
    // Estimated size of this structure is 28 bytes (3x 8-byte doubles + 4-byte int)
} Point_t;

typedef struct
{
    Point_t *corner[3];
    // A triangle consists of 3 corners.
    // Pointers are used both for size-efficiency, and so that triangles can share corners
} Triangle_t;

// The master list of triangles is a simple array of pointers.
Triangle_t* list[100] = {0};


int main(void) {
    Point_t a = {0, 0, 0, 1};
    Point_t b = {1, 0, 0, 1};
    Point_t c = {0, 1, 0, 1};
    
    Triangle_t simpleTri = { (Point_t*){&a, &b, &c} };
    
    list[0] = &simpleTri;
    
    return 0;
}
abelenky
  • 63,815
  • 23
  • 109
  • 159