简体   繁体   中英

How create a atom model in c++ with irrlicht

I am working on a project in which I show a model of a atom with protons, neutrons, and electrons. I want to show the neutrons and protons like a atom model would and so I need some points to put my points around. So I need an function like this

<list of points> getPoints(int numberOfProtonsAndNeutrons)

I have tried iterating over the latitude and longitude, but I couldn't get the intervals to work. That also is not how atom model are visually shown.

So I need an idea of how to go about creating points to put my neutrons and protons on.

Well, assuming you want some neutrons and protons in the center, with some electrons outside in various orbits (the Bohr model), then you need a few things. We can just place all the protons and neutrons on the surface of a sphere with small radius (r=1), and then place the electrons on a sphere with radius increasing depending on the orbital shell the electron is on.

Without doing all the work for you, you need will need an atom class.

It will have a member representing the orbital shell using an index: i=0 could be the innermost shell, with i>0 defining the outer shells with electrons.

You could then compute the radius of the sphere using the index as a member function. Something like

radius() { return i * ShellDist + 1; }

where ShellDist is how far apart the electron shells should be.

You can create a class for the general atom, given its shell and type.

class Atom { 
public:
  static const double ShellDist = 2; // remember to include a definition for this
  Atom(int shell) : shell(shell) {}
  virtual void radius() { return shell * ShellDist + 1; }
private:
  int shell;
};

class Electron : public Atom {
public:
  Electron(int shell) : Atom(shell) {}
};

class Neutron : public Atom {
public:
  Neutron() : Atom(0) {}
};

I'm assuming you want all the points on the sphere to be on a plane coincident with the sphere, with the plane going through the origin. To simplify this, we will just choose the circle which goes along the equator of the sphere, and then rotate it using a rotation matrix R.

So the equator circle's equation if z is the vertical axis

Vector3d 
circle(double t, double r) { return Vector3d(cos(t) * r, sin(t) * r, 0); }

If z is our vertical axis, then z is always zero here.

Then, choose a rotation matrix R using a vector math library (I'm not sure which one you are using). You can usually create a euler angle representation. Rotate it by some random fixed amount about the x and y axes. This will rotate the circle so we put all the electrons on a random circular orbit around the origin. This is using Eigen:

Transform t = AngleAxis(rand() * 2 * M_PI, Vector3d(0, 1, 0))
            * AngleAxis(rand() * 2 * M_PI, Vector3d(1, 0, 0));

Putting it together:

Vector3d createPoint(const Atom& atom, double t) {
    auto xform = AngleAxis(rand() * 2 * M_PI, Vector3d(0, 1, 0))
                 * AngleAxis(rand() * 2 * M_PI, Vector3d(1, 0, 0));
    Vector3d electronPoint = xform * circle(t, atom.shellRadius());
    return electronPoint;
}

Finally, you can add all the points together for all the atoms in your original array

vector<Vector3d> getPoints() {
  vector<shared_ptr<Atom>> atoms;
  // construct your atoms depending on the molecule
  // eg.
  atom.push_back(make_shared<Electron>(1)); // Create an electron on shell 1
  atom.push_back(make_shared<Neutron>()); // Create a neutron, which will be shell 0
  vector<Vector3d> points;
  for (const auto& atom : atoms) {
    // instead of rand() you could use some scaling 
    // of the current time to get an animation with the shells orbiting, 
    points.push_back(createPoint(atom, rand()));
  }
}

Finally, you can then pass this vector of points to irrlicht. You probably want to generate this every frame if you desire an animation.

Good luck! Irrlicht probably has a built-in matrix library which may also help. If you really want to speed things along, you could create custom vertex shaders which do all this math on the GPU, and then simply pass in electrons. This won't be necessary for any known molecules, though :). You also may want a fixed offset per electron. All of this could be done by adding parameters to the Electron and Neutron constructors, to change the start of their orbit.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM