diff options
| author | Franklin Wei <me@fwei.tk> | 2019-02-04 18:16:49 -0500 |
|---|---|---|
| committer | Franklin Wei <me@fwei.tk> | 2019-02-04 18:16:49 -0500 |
| commit | cf7eff7aab751fd1b599d967ee156c7ebb61cbbd (patch) | |
| tree | 04c414b2c7b7b42ea80e157458ac5228e04e45dd | |
| parent | f02c73a1cde15f55eac0ee2ecd0a10b6778d8b6c (diff) | |
| download | fieldviz-cf7eff7aab751fd1b599d967ee156c7ebb61cbbd.zip fieldviz-cf7eff7aab751fd1b599d967ee156c7ebb61cbbd.tar.gz fieldviz-cf7eff7aab751fd1b599d967ee156c7ebb61cbbd.tar.bz2 fieldviz-cf7eff7aab751fd1b599d967ee156c7ebb61cbbd.tar.xz | |
Work on adding toroid
| -rw-r--r-- | curve.cpp | 89 | ||||
| -rw-r--r-- | curve.h | 44 | ||||
| -rw-r--r-- | quat.cpp | 12 | ||||
| -rw-r--r-- | quat.h | 10 | ||||
| -rw-r--r-- | test.cpp | 93 | ||||
| -rw-r--r-- | vec3.cpp | 32 | ||||
| -rw-r--r-- | vec3.h | 28 |
7 files changed, 238 insertions, 70 deletions
@@ -4,15 +4,15 @@ using namespace std; -vec3 LineSegment::integrate(vec3 (*integrand)(vec3 s, vec3 ds), double dl) +vec3 LineSegment::integrate(vec3 (*integrand)(vec3 s, vec3 ds), scalar dl) const { vec3 diff = this->b - this->a, sum = 0; - double len = diff.magnitude(); + scalar len = diff.magnitude(); vec3 diffnorm = diff / len, s = this->a, ds = diffnorm * dl; - double l; + scalar l; for(l = 0; l < len; l += dl, s += ds) sum += integrand(s, ds); @@ -23,11 +23,11 @@ vec3 LineSegment::integrate(vec3 (*integrand)(vec3 s, vec3 ds), double dl) return sum; } -vec3 Arc::integrate(vec3 (*integrand)(vec3 s, vec3 ds), double dl) +vec3 Arc::integrate(vec3 (*integrand)(vec3 s, vec3 ds), scalar dl) const { //cout << "Integrating loop of length " << this->angle << " radians" << endl; - double r = this->radius.magnitude(), dtheta = dl / r; + scalar r = this->radius.magnitude(), dtheta = dl / r; //cout << "R = " << r << ", dtheta = " << dtheta << endl; @@ -35,7 +35,7 @@ vec3 Arc::integrate(vec3 (*integrand)(vec3 s, vec3 ds), double dl) //cout << "rot = " << rot << ", crot = " << crot << endl; - double len = this->angle * r, l; + scalar len = this->angle * r, l; vec3 sum = 0; @@ -63,11 +63,11 @@ vec3 Arc::integrate(vec3 (*integrand)(vec3 s, vec3 ds), double dl) return sum; } -vec3 Spiral::integrate(vec3 (*integrand)(vec3 s, vec3 ds), double dl) +vec3 Spiral::integrate(vec3 (*integrand)(vec3 s, vec3 ds), scalar dl) const { //cout << "Integrating loop of length " << this->angle << " radians" << endl; - double r = this->radius.magnitude(), dtheta = dl / r; + scalar r = this->radius.magnitude(), dtheta = dl / r; //cout << "R = " << r << ", dtheta = " << dtheta << endl; @@ -75,7 +75,8 @@ vec3 Spiral::integrate(vec3 (*integrand)(vec3 s, vec3 ds), double dl) //cout << "rot = " << rot << ", crot = " << crot << endl; - double len = this->angle * r, l; + /* only flat (doesn't include stretched length) */ + scalar len = this->angle * r, l; vec3 sum = 0; @@ -110,3 +111,73 @@ vec3 Spiral::integrate(vec3 (*integrand)(vec3 s, vec3 ds), double dl) return sum; } + +vec3 Toroid::integrate(vec3 (*integrand)(vec3 s, vec3 ds), scalar dl) const +{ + /* this applies to the minor rotation */ + scalar minor_r = this->minor_r; + + scalar major_r = this->major_radius.magnitude(); + + /* how far parallel to the major median each dl takes us */ + scalar dpar = this->pitch * dl / (2 * M_PI * minor_r) * major_r; + + /* how far each dl rotates the major vector */ + scalar major_dtheta = dpar / major_r; + + /* how long perpendicular to the major median each dl takes us (from + * Pythagoras) */ + scalar dper = sqrt(dl * dl - dpar * dpar); + + scalar minor_dtheta = dper / minor_r; + + /* minor normal is binormal to major normal and radius */ + vec3 minor_normal = this->major_normal.cross(this->major_radius).normalize(); + + /* quaternion describing rotation of minor vector */ + quat minor_rot = quat::from_angleaxis(minor_dtheta, minor_normal), minor_crot = minor_rot.conjugate(); + + quat major_rot = quat::from_angleaxis(major_dtheta, major_normal), major_crot = major_rot.conjugate(); + + vec3 sum = 0; + + quat major_radius = this->major_radius; + quat minor_radius = this->major_radius.normalize() * this->minor_r; + + for(scalar theta = 0; theta < this->major_angle; theta += major_dtheta) + { + vec3 dpar_vec = minor_normal * dpar; + vec3 ds = minor_normal.cross(minor_radius).normalize() * dper + dpar_vec; + sum += integrand(this->origin + major_radius + minor_radius, ds); + + /* we need to rotate some vectors: first the major radius and + * minor normal about the major normal, and then the minor + * radius */ + /* we also need to rotate the minor radius rotation quaternion + * about the origin */ + major_radius = major_rot * major_radius * major_crot; + minor_normal = major_rot * minor_normal * major_crot; + + minor_radius = minor_rot * minor_radius * minor_crot; + + minor_rot = minor_rot * major_rot; + minor_crot = minor_rot.conjugate(); + } + +#if 0 + if(l < len) + { + dl = len - l; + dtheta = dl / r; + rot = quat::from_angleaxis(dtheta, normal); + crot = rot.conjugate(); + dp = this->normal * dtheta * pitch / (2 * M_PI); + + vec3 ds = this->normal.cross(radius).normalize() * dl + dp; + sum += integrand(this->origin + axis + radius, ds); + } +#endif + + return sum; +} + @@ -9,7 +9,7 @@ using namespace std; class Curve { public: - virtual vec3 integrate(vec3 (*integrand)(vec3 s, vec3 ds), double delta) = 0; + virtual vec3 integrate(vec3 (*integrand)(vec3 s, vec3 ds), scalar delta) const = 0; }; class LineSegment : Curve { @@ -18,7 +18,7 @@ private: public: LineSegment(vec3 a_, vec3 b_) : a(a_), b(b_) {}; - vec3 integrate(vec3 (*integrand)(vec3 s, vec3 ds), double delta); + vec3 integrate(vec3 (*integrand)(vec3 s, vec3 ds), scalar delta) const; }; class Arc : Curve { @@ -30,11 +30,11 @@ private: vec3 radius, normal; /* how many radians the arc extends for (can be greater than 2pi) */ - double angle; + scalar angle; public: - Arc(vec3 c_, vec3 r_, vec3 n_, double th) : center(c_), radius(r_), normal(n_), angle(th) {}; + Arc(vec3 c_, vec3 r_, vec3 n_, scalar th) : center(c_), radius(r_), normal(n_), angle(th) {}; - vec3 integrate(vec3 (*integrand)(vec3 s, vec3 ds), double delta); + vec3 integrate(vec3 (*integrand)(vec3 s, vec3 ds), scalar delta) const; }; class Spiral : Curve { @@ -46,13 +46,37 @@ private: vec3 radius, normal; /* how many radians the arc extends for (can be greater than 2pi) */ - double angle; + scalar angle; - /* space between turns (2pi) */ - double pitch; + /* linear distance between turns (2pi) */ + scalar pitch; public: - Spiral(vec3 c_, vec3 r_, vec3 n_, double th, double p) : origin(c_), radius(r_), normal(n_), angle(th), pitch(p) {}; + Spiral(vec3 c_, vec3 r_, vec3 n_, scalar th, scalar p) : origin(c_), radius(r_), normal(n_), angle(th), pitch(p) {}; - vec3 integrate(vec3 (*integrand)(vec3 s, vec3 ds), double delta); + vec3 integrate(vec3 (*integrand)(vec3 s, vec3 ds), scalar delta) const; +}; + +class Toroid : Curve { +private: + vec3 origin; + + /* these are relative to the center (direction will be determined + * by RHR of normal), and should be orthonormal */ + vec3 major_radius, major_normal; + + /* "thickness" of toroid */ + scalar minor_r; + + /* how many radians (about the center) the toroid extends for + * (can be greater than 2pi) */ + scalar major_angle; + + /* central angle between successive turns (2pi rotation of small + * radius vector) */ + scalar pitch; +public: + Toroid(vec3 o, vec3 maj_r, vec3 maj_n, scalar ang, scalar min_r, scalar p) : origin(o), major_radius(maj_r), major_normal(maj_n), major_angle(ang), minor_r(min_r), pitch(p) {}; + + vec3 integrate(vec3 (*integrand)(vec3 s, vec3 ds), scalar delta) const; }; #endif @@ -1,9 +1,9 @@ #include "quat.h" #include <cmath> -quat::quat(double w_, double x_, double y_, double z_) : w(w_), x(x_), y(y_), z(z_) { } -quat::quat(double x_, double y_, double z_) : w(0), x(x_), y(y_), z(z_) { } -quat::quat(double w_, vec3 vec) : w(w_), x(vec[0]), y(vec[1]), z(vec[2]) { } +quat::quat(scalar w_, scalar x_, scalar y_, scalar z_) : w(w_), x(x_), y(y_), z(z_) { } +quat::quat(scalar x_, scalar y_, scalar z_) : w(0), x(x_), y(y_), z(z_) { } +quat::quat(scalar w_, vec3 vec) : w(w_), x(vec[0]), y(vec[1]), z(vec[2]) { } quat::quat(vec3 vec) : w(0), x(vec[0]), y(vec[1]), z(vec[2]) { } quat::quat() : w(0), x(0), y(0), z(0) { } @@ -25,10 +25,10 @@ quat quat::conjugate() const return quat(this->w, -this->x, -this->y, -this->z); } -quat quat::from_angleaxis(double angle, vec3 axis) +quat quat::from_angleaxis(scalar angle, vec3 axis) { - double si = std::sin(angle / 2); - double co = std::cos(angle / 2); + scalar si = std::sin(angle / 2); + scalar co = std::cos(angle / 2); return quat(co, si * axis[0], si * axis[1], si * axis[2]); } @@ -5,11 +5,11 @@ class quat { public: - double w, x, y, z; + scalar w, x, y, z; public: - quat(double w, double x, double y, double z); - quat(double x, double y, double z); - quat(double w, vec3 vec); + quat(scalar w, scalar x, scalar y, scalar z); + quat(scalar x, scalar y, scalar z); + quat(scalar w, vec3 vec); quat(vec3 vec); quat(); @@ -17,7 +17,7 @@ public: quat conjugate() const; - static quat from_angleaxis(double angle, vec3 axis); + static quat from_angleaxis(scalar angle, vec3 axis); }; quat operator*(const quat &, const quat &); @@ -1,6 +1,13 @@ #include <cmath> #include <iostream> +#include <fstream> +#include <sys/stat.h> +#include <sys/types.h> +#include <sstream> + +#include "vec3.h" #include "curve.h" + using namespace std; vec3 integrand(vec3 s, vec3 ds) @@ -17,7 +24,7 @@ vec3 dB(vec3 s, vec3 ds) { vec3 r = s - point; - double r2 = r.magnitudeSquared(); + scalar r2 = r.magnitudeSquared(); vec3 rnorm = r / std::sqrt(r2); @@ -26,21 +33,39 @@ vec3 dB(vec3 s, vec3 ds) //Arc loop(vec3(0, 0, 0), vec3(0, 1, 0), vec3(1, 0, 0), M_PI * 2); //Spiral loop(vec3(0, 0, 0), vec3(0, 1, 0), vec3(1, 0, 0), M_PI * 2 * 10, 1); -LineSegment loop(vec3(0, 0, 0), vec3(10, 0, 0)); +//LineSegment loop(vec3(-.1, .1, 0), vec3(.1, .1, 0)); +Toroid loop(vec3(0, 0, 0), vec3(1, 0, 0), vec3(0, 0, 1), M_PI * 2, .1, 2*M_PI / 10); + +ostream *dump_ofs = NULL; + +vec3 dump(vec3 s, vec3 ds) +{ + *dump_ofs << s << endl; + //cout << "Magn: " << ds.magnitude() << endl; + + return 0; +} + +void dump_path(ostream &out, const Curve *c) +{ + dump_ofs = &out; + c->integrate(dump, 1e-2); +} /* dump the field (gnuplot format) at z = 0 */ /* requires x0 < x1, y0 < y1 */ -void dump_field(double x0, double y0, double z0, double x1, double y1, double z1) -{ - const double delta = .2; - for(double z = z0; z <= z1; z += delta) - for(double y = y0; y <= y1; y += delta) - for(double x = x0; x <= x1; x += delta) +const scalar U0 = 4e-7 * M_PI; +const scalar I = 1; +const scalar delta = .2; + +void dump_field(scalar x0, scalar y0, scalar z0, scalar x1, scalar y1, scalar z1) +{ + for(scalar z = z0; z <= z1; z += delta) + for(scalar y = y0; y <= y1; y += delta) + for(scalar x = x0; x <= x1; x += delta) { point = vec3(x, y, z); - const double U0 = 4e-7 * M_PI; - const double I = 1; vec3 B = loop.integrate(dB, 1e-1) * U0 * I; @@ -53,6 +78,21 @@ void dump_field(double x0, double y0, double z0, double x1, double y1, double z1 } } +void dump_fieldline(ostream &out, vec3 x, scalar len) +{ + point = x; + scalar delta = .1; + while(len > 0) + { + out << point << endl; + + vec3 B = loop.integrate(dB, 1e-1) * U0 * I; + + point += delta * B; + len -= delta; + } +} + int main() { //LineSegment wire(vec3(0, -100, 0), vec3(0, 100, 0)); @@ -63,11 +103,36 @@ int main() //point = 0; - //double I = 1; + //scalar I = 1; //for(int i = 0; i < 1000; i++, point += dx) //std::cout << point[0] << " " << U0 / ( 4 * M_PI ) * loop.integrate(dB, 1e-2)[0] << endl; - - dump_field(-1, -1.5, -1.5, - 11, 1.5, 1.5); + + dump_field(-2, -2, 0, + 12, 2, 0); + //dump_field(0,0,0,0,0,0); + + stringstream ss; + ss << "curve.fld"; + ofstream ofs(ss.str()); + + dump_path(ofs, (Curve*)&loop); + + ofs.close(); + + +#if 0 + mkdir("field", 0755); + + for(scalar y = -1.5; y <= 1.5; y += .1) + { + stringstream ss; + ss << "field/" << y << ".fld"; + ofstream ofs(ss.str()); + + dump_fieldline(ofs, vec3(0, y, 0), 10); + + ofs.close(); + } +#endif } @@ -11,26 +11,26 @@ vec3::vec3() { v[1] = 0; v[2] = 0; } -vec3::vec3(double x) { +vec3::vec3(scalar x) { v[0] = x; v[1] = 0; v[2] = 0; } -vec3::vec3(double x, double y, double z) { +vec3::vec3(scalar x, scalar y, scalar z) { v[0] = x; v[1] = y; v[2] = z; } -double &vec3::operator[](int index) { +scalar &vec3::operator[](int index) { return v[index]; } -double vec3::operator[](int index) const { +scalar vec3::operator[](int index) const { return v[index]; } -vec3 vec3::operator*(double scale) const { +vec3 vec3::operator*(scalar scale) const { return vec3(v[0] * scale, v[1] * scale, v[2] * scale); } -vec3 vec3::operator/(double scale) const { +vec3 vec3::operator/(scalar scale) const { return vec3(v[0] / scale, v[1] / scale, v[2] / scale); } vec3 vec3::operator+(const vec3 &other) const{ @@ -42,13 +42,13 @@ vec3 vec3::operator-(const vec3 &other) const { vec3 vec3::operator-() const { return vec3(-v[0], -v[1], -v[2]); } -const vec3 &vec3::operator*=(double scale) { +const vec3 &vec3::operator*=(scalar scale) { v[0] *= scale; v[1] *= scale; v[2] *= scale; return *this; } -const vec3 &vec3::operator/=(double scale) { +const vec3 &vec3::operator/=(scalar scale) { v[0] /= scale; v[1] /= scale; v[2] /= scale; @@ -66,17 +66,17 @@ const vec3 &vec3::operator-=(const vec3 &other) { v[2] -= other.v[2]; return *this; } -double vec3::magnitude() const { +scalar vec3::magnitude() const { return sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); } -double vec3::magnitudeSquared() const { +scalar vec3::magnitudeSquared() const { return v[0] * v[0] + v[1] * v[1] + v[2] * v[2]; } vec3 vec3::normalize() const { - double m = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); + scalar m = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); return vec3(v[0] / m, v[1] / m, v[2] / m); } -double vec3::dot(const vec3 &other) const { +scalar vec3::dot(const vec3 &other) const { return v[0] * other.v[0] + v[1] * other.v[1] + v[2] * other.v[2]; } vec3 vec3::cross(const vec3 &other) const { @@ -85,6 +85,10 @@ vec3 vec3::cross(const vec3 &other) const { v[0] * other.v[1] - v[1] * other.v[0]); } std::ostream &operator<<(std::ostream &output, const vec3 &v) { - output << '(' << v[0] << ", " << v[1] << ", " << v[2] << ')'; - return output; + return output << v[0] << " " << v[1] << " " << v[2]; +} + +vec3 operator*(scalar scale, const vec3 &v) +{ + return v * scale; } @@ -1,30 +1,34 @@ #ifndef VEC3_H #define VEC3_H #include <iostream> + +typedef float scalar; + class vec3 { public: - double v[3]; + scalar v[3]; public: vec3(); - vec3(double x); - vec3(double x, double y, double z); - double &operator[](int index); - double operator[](int index) const; - vec3 operator*(double scale) const; - vec3 operator/(double scale) const; + vec3(scalar x); + vec3(scalar x, scalar y, scalar z); + scalar &operator[](int index); + scalar operator[](int index) const; + vec3 operator*(scalar scale) const; + vec3 operator/(scalar scale) const; vec3 operator+(const vec3 &other) const; vec3 operator-(const vec3 &other) const; vec3 operator-() const; - const vec3 &operator*=(double scale); - const vec3 &operator/=(double scale); + const vec3 &operator*=(scalar scale); + const vec3 &operator/=(scalar scale); const vec3 &operator+=(const vec3 &other); const vec3 &operator-=(const vec3 &other); - double magnitude() const; - double magnitudeSquared() const; + scalar magnitude() const; + scalar magnitudeSquared() const; vec3 normalize() const; - double dot(const vec3 &other) const; + scalar dot(const vec3 &other) const; vec3 cross(const vec3 &other) const; }; +vec3 operator*(scalar scale, const vec3 &v); std::ostream &operator<<(std::ostream &output, const vec3 &v); #endif |