2

The code below uses an octahedron as a starting 3D shape, ( I found it on the web) and after some tweaking I can't still make it work.

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stddef.h> /* must include for the offsetof macro */
#include <GL/glew.h>
#include <GL/glfw.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <stdlib.h>
#include <vector>
#include <iostream>

using namespace std; 

struct XYZ {
    GLdouble x;
    GLdouble y;
    GLdouble z;
};

struct FACET3 {
    XYZ p1;
    XYZ p2;
    XYZ p3;
};


void Normalise(XYZ *p_input)
{
    double magnitude = 0;
    magnitude = sqrt((p_input->x * p_input->x )+ (p_input->y * p_input->y) + (p_input->z * p_input->z));
    p_input->x = p_input->x / magnitude;
    p_input->y = p_input->y / magnitude;
    p_input->z = p_input->z / magnitude;

}

int CreateNSphere(FACET3 *f,int iterations)
{

   int i,it;
   double a;
   XYZ p[6] = {0,0,1,  0,0,-1,  -1,-1,0,  1,-1,0,  1,1,0, -1,1,0};
   XYZ pa,pb,pc;
   int nt = 0,ntold;

   /* Create the level 0 object */
   a = 1 / sqrt(2.0);
   for (i=0;i<6;i++) {
      p[i].x *= a;
      p[i].y *= a;
   }
   f[0].p1 = p[0]; f[0].p2 = p[3]; f[0].p3 = p[4];
   f[1].p1 = p[0]; f[1].p2 = p[4]; f[1].p3 = p[5];
   f[2].p1 = p[0]; f[2].p2 = p[5]; f[2].p3 = p[2];
   f[3].p1 = p[0]; f[3].p2 = p[2]; f[3].p3 = p[3];
   f[4].p1 = p[1]; f[4].p2 = p[4]; f[4].p3 = p[3];
   f[5].p1 = p[1]; f[5].p2 = p[5]; f[5].p3 = p[4];
   f[6].p1 = p[1]; f[6].p2 = p[2]; f[6].p3 = p[5];
   f[7].p1 = p[1]; f[7].p2 = p[3]; f[7].p3 = p[2];
   nt = 8;

   if (iterations < 1)
      return(nt);

   /* Bisect each edge and move to the surface of a unit sphere */
   for (it=0;it<iterations;it++) {
      ntold = nt;
      for (i=0;i<ntold;i++) {
         pa.x = (f[i].p1.x + f[i].p2.x) / 2;
         pa.y = (f[i].p1.y + f[i].p2.y) / 2;
         pa.z = (f[i].p1.z + f[i].p2.z) / 2;
         pb.x = (f[i].p2.x + f[i].p3.x) / 2;
         pb.y = (f[i].p2.y + f[i].p3.y) / 2;
         pb.z = (f[i].p2.z + f[i].p3.z) / 2;
         pc.x = (f[i].p3.x + f[i].p1.x) / 2;
         pc.y = (f[i].p3.y + f[i].p1.y) / 2;
         pc.z = (f[i].p3.z + f[i].p1.z) / 2;
         Normalise(&pa);
         Normalise(&pb);
         Normalise(&pc);
         f[nt].p1 = f[i].p1; f[nt].p2 = pa; f[nt].p3 = pc; nt++;
         f[nt].p1 = pa; f[nt].p2 = f[i].p2; f[nt].p3 = pb; nt++;
         f[nt].p1 = pb; f[nt].p2 = f[i].p3; f[nt].p3 = pc; nt++;
         f[i].p1 = pa;
         f[i].p2 = pb;
         f[i].p3 = pc;
      }
   }

   return(nt);
}


int main()
{
    FACET3 facet[8];
    int facets = CreateNSphere(facet, 2);
    printf(" Result: %d", facets);
} 

When I try to compile it, it returns:

"Segmentation Error"

gdb debugger says:

Program received signal SIGSEGV, Segmentation fault.
0x00000000004011df in CreateNSphere(FACET3*, int) ()

any help?

after compiling with "-g" option "gbd" returned this:

(gdb) run
Starting program: /home/alexander/Graphics/Code-Handouts/tut_3/a.out 

Program received signal SIGSEGV, Segmentation fault.
0x00000000004011df in CreateNSphere (f=0x7fffffffdeb0, iterations=2) at sphere_model.cpp:86
86           f[nt].p1 = pb; f[nt].p2 = f[i].p3; f[nt].p3 = pc; nt++;
(gdb) where
#0  0x00000000004011df in CreateNSphere (f=0x7fffffffdeb0, iterations=2) at sphere_model.cpp:86
#1  0x0000000000401303 in main () at sphere_model.cpp:100
(gdb) 
5
  • 1
    what's the stack trace (use the where or bt command in gdb)? Commented Nov 12, 2011 at 5:05
  • (gdb) where #0 0x00000000004011df in CreateNSphere(FACET3*, int) () #1 0x0000000000401303 in main () Commented Nov 12, 2011 at 5:07
  • recompile for debug (-g option), get stack trace again and edit into the question (it's easier to read that way) Commented Nov 12, 2011 at 5:09
  • Not that this makes a difference, but you should avoid mixing c and c++ headers...why use printf() when you include <iostream>? Commented Nov 12, 2011 at 5:12
  • Notice how much more informative the output is with debug information enabled? At this point, you could say p nt and you would find out that nt = 8 (or more), overrunning the array. Commented Nov 12, 2011 at 5:15

2 Answers 2

1

For two iterations, you need many more than 8 vertices.

The initial iteration, there are eight vertices.

On iteration one, 24 are added.

On iteration two, it quadruples again.

So you should declare

FACET3 facet[128];
Sign up to request clarification or add additional context in comments.

Comments

0

The size of passed array to CreateNSphere() is 8. Inside CreateNSphere() you access to yours f array by nt index variable which is incremented permanently during the loop. So basically you have memory access violation -- you tries to access f array out of it's size. When I debuged your sample gdb shown that nt was 48 when SIGSEGV received.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.