writing Ascii stl file for cylinder

Hi, Im trying to write a code that can generate Ascii stl file to make cylinder.
main:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "Cube.hh"
#include "Cylinder.hh"


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");


Cube.hh:
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
#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";
};


Cylinde.hh:
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
#pragma once
#include "Shape.hh"
#include <iostream>
#include <fstream>
#include <cmath>

using namespace std;

class Cylinder : public Shape {
private:
    double r, h, fn;

    void facet(ostream &s, double x1, double y1, double z1, double x2, double y2, double z2, double x3, double y3,
               double z3) {
        float x ,y;
        float
        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";
    }

}
public:
    Cylinder(double x_ , double y_, double z_, double r_ ,double h_ , double fn_) : Shape(x_, y_ , z_) ,r(r_) ,  h(h_) , fn(fn_) {}
void print (const char filename[]){
        ofstream f(filename);
        f << "solid Cylinder \n" ;
        f << "endsolid Cylinder \n";

    }

};

#endif 


Shape.hh:
1
2
3
4
5
6
7
8
9
10
#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;
};




I not sure how do I construct my cylinder.hh any help I could get?
What exactly is it that you need help for? You seems to have your code for cylinder.hh which is simialr to cube.
You need to decide how you are going to specify the orientation of your cylinder and cube.

You can view the output of the following code (file stl.stl) by dragging and dropping it into an online viewer; e.g.
https://www.viewstl.com/

For the file format I'm just using the ASCII STL format from
https://en.wikipedia.org/wiki/STL_(file_format)

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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cmath>
using namespace std;

const double PI = 4.0 * atan( 1.0 );
class STL;

//======================================================================

struct vec
{
   double x, y, z;
};

//----------------------------

vec operator + ( const vec a, const vec b ){ return { a.x + b.x, a.y + b.y, a.z + b.z }; }
vec operator - ( const vec a, const vec b ){ return { a.x - b.x, a.y - b.y, a.z - b.z }; }
vec operator / ( const vec a, double d    ){ return { a.x / d, a.y / d, a.z / d }; }
vec operator * ( double d   , const vec a ){ return { d * a.x, d * a.y, d * a.z }; }
vec operator * ( const vec a, const vec b ){ return { a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x }; }
double normsq  ( const vec a              ){ return a.x * a.x + a.y * a.y + a.z * a.z; }
double len     ( const vec a              ){ return sqrt( normsq( a ) ); }
ostream & operator << ( ostream &out, const vec a ){ return out << a.x << " " << a.y << " " << a.z << " "; }

//======================================================================

struct Triangle
{
   vec v1, v2, v3;
};

//======================================================================

class Shape
{
public:
   virtual void addToPlot( STL &stl ) = 0;
};

//======================================================================

class STL
{
   vector<Triangle> triangles;
public:
   void add( Shape *S );
   void addTriangle( vec v1, vec v2, vec v3 );
   void addRectangle( vec v1, vec v2, vec v3, vec v4 );
   void draw( const string &filename );
};

//----------------------------

void STL::add( Shape *S )
{
   S->addToPlot( *this );
}

//----------------------------

void STL::addTriangle( vec v1, vec v2, vec v3 )
{
   triangles.push_back( { v1, v2, v3 } );
}

//----------------------------

void STL::addRectangle( vec v1, vec v2, vec v3, vec v4 )
{
   addTriangle( v1, v2, v3 );
   addTriangle( v1, v3, v4 );
}

//----------------------------

void STL::draw( const string &filename )
{
   ofstream out( filename );
   out << "solid\n";

   for ( Triangle tri : triangles )
   {
      vec n = ( tri.v2 - tri.v1 ) * ( tri.v3 - tri.v1 );
      n = n / len( n );                // unit normal vector;

      out << "   facet normal " << n << '\n';
      out << "      outer loop\n";
      out << "         vertex " << tri.v1 << '\n';
      out << "         vertex " << tri.v2 << '\n';
      out << "         vertex " << tri.v3 << '\n';
      out << "      endloop\n";
      out << "   endfacet\n";
   }

   out << "endsolid\n";
}

//======================================================================

class Cube : public Shape
{
   vec centre;                         // centre
   double L;                           // side length
   vec side1, side2, side3;            // TO DO: needs general orientation

public:
   Cube( vec centre, double L ) : centre( centre ), L( L )       // Specify centre and side length
   {
      side1 = vec{ L, 0, 0 };
      side2 = vec{ 0, L, 0 };
      side3 = vec{ 0, 0, L };
   }
   Cube( vec centre, vec side1, vec side2 ) : centre( centre ), side1( side1 ), side2( side2 )
   {                                                             // Specify centre and two side vectors
      L = len( side1 );
      side3 = side1 * side2 / L;
   }
   void addToPlot( STL &stl );
};

//----------------------------

void Cube::addToPlot( STL &stl )
{
   vec v1 = centre - 0.5 * ( side1 + side2 + side3 );
   vec v2 = v1 + side1;
   vec v3 = v2 + side2;
   vec v4 = v3 - side1;
   vec v5 = v1 + side3, v6 = v2 + side3, v7 = v3 + side3, v8 = v4 + side3;
   stl.addRectangle( v1, v2, v6, v5 );
   stl.addRectangle( v2, v3, v7, v6 );
   stl.addRectangle( v3, v4, v8, v7 );
   stl.addRectangle( v4, v1, v5, v8 );
   stl.addRectangle( v1, v4, v3, v2 );
   stl.addRectangle( v5, v6, v7, v8 );
}

//======================================================================

class Cylinder : public Shape
{
   vec centre;                                             // centre (NOT base centre)
   double r;                                               // radius
   double h;                                               // height
   int nface;                                              // number of rectangular faces
   vec side1, side2, side3;                                // vectors along radius, along radius perpendicular, along axis

public:
   Cylinder( vec centre, double r, double h, int n = 30 ) : centre( centre ), r( r ), h( h ), nface( n )
   {                                                       // Specify centre, radius, height
      side1 = vec{ r, 0, 0 };
      side2 = vec{ 0, r, 0 };
      side3 = vec{ 0, 0, h };
   }
   Cylinder( vec centre, vec side1, vec side3, int n = 30 ) : centre( centre ), side1( side1 ), side3( side3 ), nface(n)
   {                                                       // Specify vectors for centre, radius, height
      r = len( side1 );
      h = len( side3 );
      side2 = side3 * side1 / h;
   }
   void addToPlot( STL &stl );
};

//----------------------------

void Cylinder::addToPlot( STL &stl )
{
   vec bottom = centre - 0.5 * side3;                      // centre of base
   vec top    = bottom + side3;                            // centre of top

   double dtheta = 2.0 * PI / nface;
   vec v1, v2, v3, v4;
   v2 = bottom + side1;
   v3 = v2 + side3;
   for ( int n = 1; n <= nface; n++ )
   {
      double theta = n * dtheta;
      v1 = v2;
      v4 = v3;
      v2 = bottom + cos( theta ) * side1 + sin( theta ) * side2;
      v3 = v2 + side3;
      stl.addRectangle( v1, v2, v3, v4 );                  // add sides as a series of rectangles
      stl.addTriangle( v2, v1, bottom );                   // add triangles for bottom
      stl.addTriangle( v4, v3, top    );                   // add triangles for top
   }
}

//======================================================================

int main()
{
   Cube cube1( vec{  0, 0, 0 }, 25 );
   Cube cube2( vec{ 50, 0, 0 }, vec{ 20, 20, 0 }, vec{ 20, -20, 0 } );
   Cylinder cylinder1( vec{  0, 50, 0 }, 20, 30 );
   Cylinder cylinder2( vec{ 50, 50, 0 }, vec{ 20, 20, 0 }, vec{ 20, -20, 0 } );

   STL stl;
   stl.add( &cube1 );
   stl.add( &cube2 );
   stl.add( &cylinder1 );
   stl.add( &cylinder2 );
   stl.draw( "stl.stl" );
}

Last edited on
Topic archived. No new replies allowed.