having trouble with my hw for stl file

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
*
	separate compilation
	Cube.hh
	Cube.cc
	Cylinder.hh
	Cylinder.cc
optional:
	Sphere.hh
	Sphere.cc
	Drawing.cc
	Drawing.hh
 */
#include "Cube.hh"
#include "Cylinder.hh"
#include <iostream>
#include <cmath>

using namespace std;
int main() {
    //translate([0,10,0]) cube(25);
    Cube c(0,10,0, 25); // make a 25x25x25 cube at location (0,10,0)
    c.print("cube.stl");

    //translate([100,0,0]) cylinder(r=20,h=50, $fn=30);

    // center of base circle x=100, y=0, z=0 r=20 h=50, number of facets = 30
    Cylinder cyl(100, 0, 0, 20, 50, 30);
    c.print("cyl.stl");

    //%50 bonus
    // (x,y,z)           r,  numfacets
    Sphere s(-50,50,50,  25, 10);
    s.print("sphere.stl");

    //+%100%
    Drawing d; // constructor, destructor, ...
    d.add(new Cube(0,10,0,25));
    d.add(new Cylinder(100,0,0,20,50,30));
    d.print("drawing.stl");
}




This is the code I have for assigment which require separate compulation that able to generate 3d drawing as an output. And I have no idea where to start :(

Any reference or help I could get?
Last edited on
Please edit your post and add code formatting with [code] and [/code] tags around your program.

It appears the file format you're talking about is https://en.wikipedia.org/wiki/STL_%28file_format%29
I assume your instructor wants you to use the ASCII version, as that is probably easier for a beginner to grasp.
I assume your instructor would have some sort of example for you to look at if they expect you to generate stl files, but essentially you need your file to look something like:

solid name
facet normal ni nj nk
    outer loop
        vertex v1x v1y v1z
        vertex v2x v2y v2z
        vertex v3x v3y v3z
    endloop
endfacet

See the wikipedia page for more details.

Focus on one thing at a time, and build up your program slowly. Start small. The cube is probably the easiest shape to generate, because it's just 2 * 6 triangles you need to generate. You'd probably want a program that can read these files to know if you're generating them correctly.

I don't know what compiler you are using, but this shows separate compilation using g++:
http://web-ext.u-aizu.ac.jp/~fayolle/teaching/2012/C++/pdf/1-separate_compilation.pdf

If you're using an IDE, it should do separate compilation automatically, just make sure you create the files you need (Cube.hh, Cube.cc, etc.)
Last edited on
1. Im using clion and MinGW for gnu.
2. Reason I'm so confusing is, as like you assume lots of things, this main is only thing I get for assignment and have no idea where to start. Apparently, instructor want me to simply write into program called openscad.
Okay, so OpenSCAD is eventually what will be opening the files you create, so that is how you can check your results to make sure they look correct. I am not familiar with OpenSCAD itself, but I looked it up and it can definitely handle .stl files.

Quick Tip: Import and Edit STL Files in OpenSCAD
https://www.youtube.com/watch?v=KRfTj2AXiYM

Here is what the ASCII STL file would look like for a cube, according to this webpage:
https://people.sc.fsu.edu/~jburkardt/data/stla/stla.html
See: https://people.sc.fsu.edu/~jburkardt/data/stla/cube.stl
solid MYSOLID
  facet normal  0.0   0.0  -1.0    
    outer loop
      vertex    0.0   0.0   0.0    
      vertex    1.0   1.0   0.0    
      vertex    1.0   0.0   0.0    
    endloop
  endfacet
  facet normal  0.0   0.0  -1.0    
    outer loop
      vertex    0.0   0.0   0.0 
      vertex    0.0   1.0   0.0    
      vertex    1.0   1.0   0.0    
    endloop
  endfacet
  facet normal -1.0   0.0   0.0    
    outer loop
      vertex    0.0   0.0   0.0
      vertex    0.0   1.0   1.0
      vertex    0.0   1.0   0.0
    endloop
  endfacet
  facet normal -1.0   0.0   0.0    
    outer loop
      vertex    0.0   0.0   0.0
      vertex    0.0   0.0   1.0
      vertex    0.0   1.0   1.0
    endloop
  endfacet
  facet normal  0.0   1.0   0.0    
    outer loop
      vertex    0.0   1.0   0.0
      vertex    1.0   1.0   1.0
      vertex    1.0   1.0   0.0
    endloop
  endfacet
  facet normal  0.0   1.0   0.0    
    outer loop
      vertex    0.0   1.0   0.0
      vertex    0.0   1.0   1.0
      vertex    1.0   1.0   1.0
    endloop
  endfacet
  facet normal  1.0   0.0   0.0    
    outer loop
      vertex    1.0   0.0   0.0
      vertex    1.0   1.0   0.0
      vertex    1.0   1.0   1.0
    endloop
  endfacet
  facet normal  1.0   0.0   0.0    
    outer loop
      vertex    1.0   0.0   0.0
      vertex    1.0   1.0   1.0
      vertex    1.0   0.0   1.0
    endloop
  endfacet
  facet normal  0.0  -1.0   0.0    
    outer loop
      vertex    0.0   0.0   0.0
      vertex    1.0   0.0   0.0
      vertex    1.0   0.0   1.0
    endloop
  endfacet
  facet normal  0.0  -1.0   0.0    
    outer loop
      vertex    0.0   0.0   0.0
      vertex    1.0   0.0   1.0
      vertex    0.0   0.0   1.0
    endloop
  endfacet
  facet normal  0.0   0.0   1.0    
    outer loop
      vertex    0.0   0.0   1.0
      vertex    1.0   0.0   1.0
      vertex    1.0   1.0   1.0
    endloop
  endfacet
  facet normal  0.0   0.0   1.0    
    outer loop
      vertex    0.0   0.0   1.0
      vertex    1.0   1.0   1.0
      vertex    0.0   1.0   1.0
    endloop
  endfacet
endsolid MYSOLID


That page has other examples as well, including a sphere.
It may look complicated, but essentially it's just a bunch of triangles that eventually make up the whole shape.
For the circular face of a cylinder, think of it like triangular pizza slices around a center vertex. So each outer point would be { cos(angle), sin(angle), some height }, where angle is incremented from 0 to 2 Pi.

That's what you need your program to write out to a file. I suggest using loops/arrays.
Last edited on
Thanks for the reference. I wil try to write a loop for this, but not sure I really capable of haha....
I wrote my code for Cube.hh ( header being hh because thats what instructor wants)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
 
#pragma once
#include <iostream>
#include "Shape.hh"
#include <cmath>
#include<fstream>

using namespace std;
class Cube : public Shape {
private:
    double s;

    void facet(ostream &s, double x1, double y1, double z1, double x2, double y2, double z2, double x3, double y3,
               double z3) {
        double Ax = x2 - x1;
        double Ay = y2 - y1;
        double Az = z2 - z1;
        double Bx = x3 - x1;
        double By = y3 - y1;
        double Bz = z3 - z1;
        double nx = Ay * Bz - Az * By;
        double ny = Az * Bx - Ax * Bz;
        double nz = Ax * Bz - Ay * Bx;
        s << "facet normal " << nx << " " << ny << " " << nz << "\n";
        s << "outer loop\n";
        s << "vertex" << x1 << " " << y1 << " " << z1 << "\n";
        s << "vertex" << x2 << " " << y2 << " " << z2 << "\n";
        s << "vertex" << x3 << " " << y3 << " " << z3 << "\n";
        s << "endloop\n";
        s << "endfacet\n";
    }

    void
    rectangleFace(ostream &s, double x1, double y1, double z1, double x2, double y2, double z2, double x3, double y3,
                  double z3, double x4, double y4, double z4) {
        facet(s, x1, y1, z1, x2, y2, z2, x3, y3, z3);
        facet(s, x1,y1,z1 , x3,y3,z3 , x4,y4,z4);   // it may be x1,y1,z1 , x3,y3,z3 , x4,y4,z4
    }

public:
    Cube(double x_, double y_, double z_ , double s_) : Shape(x_, y_ , z_) , s(s_) {}
void print (const char filename[]) {
ofstream f(filename);
    f << "solid Cube \n" ;
rectangleFace(f,x,y,z, x+s,y,z , x+s,y+s,z, x,y+s,z);
rectangleFace(f,x,y,z , x,y+s,z+s , x,y+s,z, x,y,z+s);
rectangleFace(f,x,y+s,z , x+s,y+s,z+s , x+s,y+s,z , x,y+s,z+s );
rectangleFace(f,x+s,y,z , x+s,y+s,z , x+s,y+s,z+s , x+s,y,z+s );
rectangleFace(f,x,y,z , x+s,y,z , x+s,y,z+s , x,y,z+s );
rectangleFace(f,x,y,z+s , x+s,y,z+s , x+s,y+s,z+s , x,y+s,z+s );
   f<<"endsolid Cube\n";
};

Shape.hh
1
2
3
4
5
6
7
8
#pragma once
class Shape {
protected:
    double x,y,z;
public:
    Shape(double x, double y , double z): x(x) , y(y) , z(z){}
   //virtual  double area() const = 0;
};




Can I get help for cylinder ? I understand what I need for cylinder but not sure how do I write that in c++
Last edited on
Forgot to give a reply earlier. I'm kind of just winging this, but you need to generate:
(1) top triangle for circular slice
(2) 2x side triangles for each "side" of cylinder
(3) bottom triangle for circular slice

Maybe this will help you, and you can adapt from it:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;

struct Vertex {
    double x;
    double y;
    double z;
};

struct Triangle {
    Vertex a;
    Vertex b;
    Vertex c;
};

std::ostream& operator<<(std::ostream& os, const Vertex& vertex)
{
    os << "(" << vertex.x << ", " << vertex.y << ", " << vertex.z << ")";
    return os;
}

std::ostream& operator<<(std::ostream& os, const Triangle& triangle)
{
    os << "[ " << triangle.a << ", " << triangle.b << ", " << triangle.c << " ]";
    return os;
}

const double Pi = 3.14159265358979323846;

int main()
{
    int NumEdges = 10; // number of triangular wedges in circle/sides
                       // you probably want to increase this.
    
    std::vector<Triangle> triangles; // (could pre-size @ 4 * NumEdges)
    
    double height = 10.0;
    
    Vertex bottom_center {0, 0, 0};
    double bottom_z = bottom_center.z;

    Vertex top_center {bottom_center.x, bottom_center.y, bottom_center.z + height};
    double top_z = top_center.z;
    
    double radius = 3.0;
    
    for (int i = 0; i < NumEdges; i++)
    {
        double t = static_cast<double>(i) / NumEdges; // [0, (NumEdges - 1)/NumEdges]
        double t_next = static_cast<double>(i+1) / NumEdges; // [1/NumEdges, 1]

        double x = bottom_center.x + radius * std::cos(2*Pi * t);
        double y = bottom_center.y + radius * std::sin(2*Pi * t);
        double x_next = bottom_center.x + radius * std::cos(2*Pi * t_next);
        double y_next = bottom_center.y + radius * std::sin(2*Pi * t_next);
        
        // (1.) top triangle for circular slice
        triangles.push_back({
            top_center,
            Vertex{x,      y,      top_z},
            Vertex{x_next, y_next, top_z}
        });
        
        // (2.) 2x side triangles for each "side" of cylinder
        triangles.push_back({
            Vertex{x,      y,      bottom_z},
            Vertex{x_next, y_next, bottom_z},
            Vertex{x_next, y_next, top_z}
        });
        triangles.push_back({
            Vertex{x,      y,      bottom_z},
            Vertex{x_next, y_next, top_z},
            Vertex{x,      y,      top_z}
        });
        
        // (3.) bottom triangle for circular slice
        triangles.push_back({
            bottom_center,
            Vertex{x_next, y_next, top_z},
            Vertex{x,      y,      top_z}
        });
    }

    for (const Triangle& tri : triangles)
    {
        cout << tri << '\n';
    }

    return 0;
}

It compiles, and the points look OK in Matlab, but I didn't completely check it for accuracy.
Last edited on
Topic archived. No new replies allowed.