예제 #1
0
 public Compound()
 {
     name        = "";
     atoms       = new List <Atom>();
     crystalCell = new CrystalCell();
     dummy       = false;
 }
예제 #2
0
        private void BuildCompound()
        {
            if (!_compoundSelected || !_groupSelected)
            {
                return;
            }

            _multipliedAtoms.Clear();
            MainViewport.Children.Clear();

            _atomCell = _compound.CrystalCell;
            try
            {
                _compoundVisual =
                    new CompoundVisual(_compound, _selectedSpaceGroup, _selectableModels, _multipliedAtoms);
            }
            catch (EvaluateException)
            {
                MessageBox.Show("Ошибка в записях пространственной группы! Ячейка построена неправильно!");
                return;
            }


            MainViewport.Children.Add(_compoundVisual);
            MoveFromCenter(_compoundVisual);

            ModelBuilder.BuildDiscreteAxis(out _discreteYAxis, out _discreteXAxis, out _discreteZAxis, _atomCell);


            _discreteAxisGroup.Children.Clear();
            _discreteAxisGroup.Children.Add(_discreteXAxis);
            _discreteAxisGroup.Children.Add(_discreteYAxis);
            _discreteAxisGroup.Children.Add(_discreteZAxis);

            ModelVisual3D axisModelVisual = new ModelVisual3D();

            AmbientLight     ambientLight     = new AmbientLight(Colors.Gray);
            DirectionalLight directionalLight =
                new DirectionalLight(Colors.Gray, new Vector3D(-1.0, -3.0, -2.0));

            _discreteAxisGroup.Children.Add(ambientLight);
            _discreteAxisGroup.Children.Add(directionalLight);

            axisModelVisual.Content = _discreteAxisGroup;
            AxisViewport.Children.Add(axisModelVisual);
        }
예제 #3
0
        private static double CalculatePolyhedronVolume(List <Atom> oxygenAtoms, CrystalCell crystalCell)
        {
            Vector3D aVector = new Vector3D(oxygenAtoms[0].X * crystalCell.YAxisL, oxygenAtoms[0].Y * crystalCell.ZAxisL, oxygenAtoms[0].Z * crystalCell.XAxisL);
            Vector3D bVector = new Vector3D(oxygenAtoms[1].X * crystalCell.YAxisL, oxygenAtoms[1].Y * crystalCell.ZAxisL, oxygenAtoms[1].Z * crystalCell.XAxisL);
            Vector3D cVector = new Vector3D(oxygenAtoms[2].X * crystalCell.YAxisL, oxygenAtoms[2].Y * crystalCell.ZAxisL, oxygenAtoms[2].Z * crystalCell.XAxisL);
            Vector3D dVector = new Vector3D(oxygenAtoms[3].X * crystalCell.YAxisL, oxygenAtoms[3].Y * crystalCell.ZAxisL, oxygenAtoms[3].Z * crystalCell.XAxisL);

            var volume = Math.Abs(
                Vector3D.DotProduct(
                    Vector3D.Subtract(aVector, dVector),
                    Vector3D.CrossProduct(
                        Vector3D.Subtract(bVector, dVector),
                        Vector3D.Subtract(cVector, dVector)
                        )
                    )
                );

            return(volume);
        }
예제 #4
0
 private void Window_Loaded(object sender, RoutedEventArgs e)
 {
     _groupSelected         = false;
     _compoundSelected      = false;
     _xLabel.Content        = "Y";
     _yLabel.Content        = "Z";
     _zLabel.Content        = "X";
     _xLabel.FontSize       = 25;
     _yLabel.FontSize       = 25;
     _zLabel.FontSize       = 25;
     _multipliedAtoms       = new List <Atom>();
     _atomCell              = new CrystalCell();
     _theCamera.Width       = 90;
     _axisSceneCamera.Width = 90;
     MainViewport.Camera    = _theCamera;
     AxisViewport.Camera    = _axisSceneCamera;
     _theCamera.PositionCamera(_atomCell);
     _axisSceneCamera.PositionCamera();
 }
예제 #5
0
        public static List <Atom> CalculatePolyhedra(List <Atom> atoms, double Yx, double Zy, double Xz, CrystalCell crystalCell)
        {
            List <Atom> oxygensWithTranslations = new List <Atom>();
            var         result  = atoms.Where(a => a.Element[0] == 'O');
            List <Atom> oxygens = result.ToList();

            foreach (Atom ox in oxygens)
            {
                AddToList(oxygensWithTranslations, ox);
                AddToList(oxygensWithTranslations, new Atom(ox.Element, (ox.X + 1).ToString(), ox.Y.ToString(), ox.Z.ToString(), ox.Brush));
                AddToList(oxygensWithTranslations, new Atom(ox.Element, (ox.X - 1).ToString(), ox.Y.ToString(), ox.Z.ToString(), ox.Brush));
                AddToList(oxygensWithTranslations, new Atom(ox.Element, ox.X.ToString(), (ox.Y + 1).ToString(), ox.Z.ToString(), ox.Brush));
                AddToList(oxygensWithTranslations, new Atom(ox.Element, ox.X.ToString(), (ox.Y - 1).ToString(), ox.Z.ToString(), ox.Brush));
                AddToList(oxygensWithTranslations, new Atom(ox.Element, ox.X.ToString(), ox.Y.ToString(), (ox.Z + 1).ToString(), ox.Brush));
                AddToList(oxygensWithTranslations, new Atom(ox.Element, ox.X.ToString(), ox.Y.ToString(), (ox.Z - 1).ToString(), ox.Brush));
            }

            List <Atom> allOxygens = new List <Atom>();

            foreach (Atom atom in atoms.Where(a => a.Element[0] != 'O'))
            {
                var res = oxygensWithTranslations.Where(a => a.Element[0] == 'O').OrderBy(a => Distance(atom, a)).Take(4); //oxygens_with_translations
                if (CheckIfPointIsInTetrahydron(atom, res.ToList()))
                {
                    allOxygens            = allOxygens.Concat(res.ToList()).ToList();
                    atom.hasPolyhedra     = true;
                    atom.PolyhedraAtoms   = res.ToList();
                    atom.PolyhedronVolume = CalculatePolyhedronVolume(res.ToList(), crystalCell);
                }
            }

            return(allOxygens);
        }
예제 #6
0
        public AtomVisual(Atom atom, string atomColor, SpaceGroupCl selectedSpaceGroup, CrystalCell atomCell,
                          List <Atom> multipliedAtoms, double xAxisL = 0, double yAxisL = 0, double zAxisL = 0)
        {
            if (selectedSpaceGroup == null)
            {
                throw new NotImplementedException();
            }

            this.atom = atom;

            Content = MiscModel3DGroup;

            double atomVisualSize = 0.4;

            if (atom.Element[0] == 'O' && (atom.Element[1] != 's'))
            {
                atomVisualSize = 0.2;
            }

            //Model3DGroup atomRepro = new Model3DGroup();
            List <Atom> atomReproList = new List <Atom>();

            for (int i = 0; i < selectedSpaceGroup.Expressions.Length; i += 3)
            {
                double X = SpaceGroupCl.Evaluate(selectedSpaceGroup.Expressions[i + 1], 0, atom.Y, 0); //сухие координаты
                double Y = SpaceGroupCl.Evaluate(selectedSpaceGroup.Expressions[i + 2], 0, 0, atom.Z);
                double Z = SpaceGroupCl.Evaluate(selectedSpaceGroup.Expressions[i], atom.X, 0, 0);


                if (X < 0)
                {
                    X += 1;
                }
                if (Y < 0)
                {
                    Y += 1;
                }
                if (Z < 0)
                {
                    Z += 1;
                }

                if (X > 1)
                {
                    X -= 1;
                }
                if (Y > 1)
                {
                    Y -= 1;
                }
                if (Z > 1)
                {
                    Z -= 1;
                }

                //
                double a = atomCell.YAxisL;
                double b = atomCell.ZAxisL;
                double c = atomCell.XAxisL;

                double xC = c * Math.Cos(ToRadians(atomCell.Gamma));
                double yC = (b * c * Math.Cos(ToRadians(atomCell.Beta)) - xC * b * Math.Cos(ToRadians(atomCell.Alpha))) /
                            b * Math.Sin(ToRadians(atomCell.Alpha));
                double zC = Math.Sqrt(c * c - xC * xC - yC * yC);

                Vector3D xVector  = new Vector3D(a * X, 0, 0);
                Vector3D oyVector = new Vector3D(b * Math.Cos(ToRadians(atomCell.Alpha)) * Y, b * Math.Sin(ToRadians(atomCell.Alpha)) * Y, 0);
                Vector3D zVector  = new Vector3D(xC * Z, yC * Z, zC * Z);

                Vector3D xyVector  = Vector3D.Add(xVector, oyVector);
                Vector3D xyzVector = Vector3D.Add(xyVector, zVector);
                //

                var addedAtom = new Atom(atom.Element, Z.ToString(), X.ToString(), Y.ToString(), null);
                if (multipliedAtoms.Contains(addedAtom))
                {
                    continue;
                }
                multipliedAtoms.Add(addedAtom);
                AtomVisual multipliedAtomVisual = new AtomVisual((Point3D)xyzVector, atomVisualSize, atomColor, addedAtom);
                Children.Add(multipliedAtomVisual);
                atomReproList.Add(new Atom(atom.Element, Z.ToString(), X.ToString(), Y.ToString(), atom.Brush));
            }
        }
예제 #7
0
 public static void PositionCamera(this OrthographicCamera TheCamera, CrystalCell atomCell)
 {
     TheCamera.Position      = new Point3D(0, atomCell.ZAxisL / 2, +50);
     TheCamera.LookDirection = new Vector3D(0, 0, -1);
     TheCamera.UpDirection   = new Vector3D(0, 1, 0);
 }
예제 #8
0
        public static GeometryModel3D DrawSinglePolyhedra(this MeshGeometry3D polyhedraMesh, Atom atom, CrystalCell atomCell, int nOfVertices)
        {
            // GENERAL CASE//

            int     i      = 0;
            Point3D point0 = new Point3D(atom.PolyhedraAtoms[i].Y * atomCell.YAxisL, atom.PolyhedraAtoms[i].Z * atomCell.ZAxisL, atom.PolyhedraAtoms[i].X * atomCell.XAxisL);
            Point3D point1 = new Point3D(atom.PolyhedraAtoms[i + 1].Y * atomCell.YAxisL, atom.PolyhedraAtoms[i + 1].Z * atomCell.ZAxisL, atom.PolyhedraAtoms[i + 1].X * atomCell.XAxisL);
            Point3D point2 = new Point3D(atom.PolyhedraAtoms[i + 2].Y * atomCell.YAxisL, atom.PolyhedraAtoms[i + 2].Z * atomCell.ZAxisL, atom.PolyhedraAtoms[i + 2].X * atomCell.XAxisL);
            Point3D point3 = new Point3D(atom.PolyhedraAtoms[i + 3].Y * atomCell.YAxisL, atom.PolyhedraAtoms[i + 3].Z * atomCell.ZAxisL, atom.PolyhedraAtoms[i + 3].X * atomCell.XAxisL);

            AddSegment(polyhedraMesh, point0, point1, new Vector3D(0, 1, 0), 0.04);
            AddSegment(polyhedraMesh, point0, point2, new Vector3D(0, 1, 0), 0.04);
            AddSegment(polyhedraMesh, point0, point3, new Vector3D(0, 1, 0), 0.04);
            AddSegment(polyhedraMesh, point1, point3, new Vector3D(0, 1, 0), 0.04);
            AddSegment(polyhedraMesh, point1, point2, new Vector3D(0, 1, 0), 0.04);
            AddSegment(polyhedraMesh, point2, point3, new Vector3D(0, 1, 0), 0.04);

            AddTriangle(polyhedraMesh, point0, point1, point2);
            AddTriangle(polyhedraMesh, point0, point1, point3);
            AddTriangle(polyhedraMesh, point1, point2, point3);
            AddTriangle(polyhedraMesh, point0, point2, point3);


            DiffuseMaterial qDiffTransYellow =
                new DiffuseMaterial(new SolidColorBrush(System.Windows.Media.Color.FromArgb(64, 255, 255, 0)));

            SpecularMaterial qSpecTransWhite =
                new SpecularMaterial(new SolidColorBrush(System.Windows.Media.Color.FromArgb(128, 255, 255, 255)), 30.0);
            MaterialGroup qOuterMaterial = new MaterialGroup();

            qOuterMaterial.Children.Add(qDiffTransYellow);
            qOuterMaterial.Children.Add(qSpecTransWhite);

            GeometryModel3D polyhedraModel = new GeometryModel3D(polyhedraMesh, qOuterMaterial);

            polyhedraModel.BackMaterial = qOuterMaterial;

            return(polyhedraModel);
        }
예제 #9
0
        public static void BuildDiscreteAxis(out GeometryModel3D discreteYAxisModel, out GeometryModel3D discreteXAxisModel, out GeometryModel3D discreteZAxisModel, CrystalCell crystalCell)
        {
            MeshGeometry3D xMesh  = new MeshGeometry3D();
            MeshGeometry3D yMesh  = new MeshGeometry3D();
            MeshGeometry3D zMesh  = new MeshGeometry3D();
            Point3D        origin = new Point3D(0, 0, 0);

            const double length = 5;

            double a = length;
            double b = length;
            double c = length;

            //Y (normal: X):

            Point3D xmax = new Point3D(5, 0, 0);

            yMesh.AddSegment(origin, xmax, new Vector3D(0, 1, 0), 0.1);

            Vector3D vX = xmax - origin;

            vX.Normalize();
            Vector3D perpX = Vector3D.CrossProduct(vX, new Vector3D(0, 1, 0));

            perpX.Normalize();
            Vector3D v1X = ScaleVector(-vX + perpX, 1);
            Vector3D v2X = ScaleVector(-vX - perpX, 1);

            yMesh.AddSegment(xmax, xmax + v1X, new Vector3D(0, 1, 0), 0.1);
            yMesh.AddSegment(xmax, xmax + v2X, new Vector3D(0, 1, 0), 0.1);

            Vector3D perpX1 = Vector3D.CrossProduct(vX, new Vector3D(0, 0, 1));

            perpX1.Normalize();
            Vector3D v1X1 = ScaleVector(-vX + perpX1, 1);
            Vector3D v2X1 = ScaleVector(-vX - perpX1, 1);

            yMesh.AddSegment(xmax, xmax + v1X1, new Vector3D(0, 0, 1), 0.1);
            yMesh.AddSegment(xmax, xmax + v2X1, new Vector3D(0, 0, 1), 0.1);

            SolidColorBrush axesBrush     = Brushes.Green;
            DiffuseMaterial yAxisMaterial = new DiffuseMaterial(axesBrush);

            discreteYAxisModel = new GeometryModel3D(yMesh, yAxisMaterial);

            //Z (normal: Y):

            double x_c = c * Math.Cos(ToRadians(crystalCell.Alpha));

            double y_c = (b * c * Math.Cos(ToRadians(crystalCell.Beta)) - x_c * b * Math.Cos(ToRadians(crystalCell.Gamma)))
                         / b * Math.Sin(ToRadians(crystalCell.Gamma));


            //double z_c = c * c - x_c * x_c - y_c * y_c;

            Point3D yMax = new Point3D(x_c, 5, y_c);

            zMesh.AddSegment(origin, yMax, new Vector3D(1, 0, 0), 0.1);

            Vector3D vY = yMax - origin;

            vY.Normalize();
            Vector3D perpY = Vector3D.CrossProduct(vY, new Vector3D(1, 0, 0));

            perpX.Normalize();
            Vector3D v1Y = ScaleVector(-vY + perpY, 1);
            Vector3D v2Y = ScaleVector(-vY - perpY, 1);

            zMesh.AddSegment(yMax, yMax + v1Y, new Vector3D(0, 1, 0), 0.1);
            zMesh.AddSegment(yMax, yMax + v2Y, new Vector3D(0, 1, 0), 0.1);

            Vector3D perpY1 = Vector3D.CrossProduct(vY, new Vector3D(0, 0, 1));

            perpX1.Normalize();
            Vector3D v1Y1 = ScaleVector(-vY + perpY1, 1);
            Vector3D v2Y1 = ScaleVector(-vY - perpY1, 1);

            zMesh.AddSegment(yMax, yMax + v1Y1, new Vector3D(0, 0, 1), 0.1);
            zMesh.AddSegment(yMax, yMax + v2Y1, new Vector3D(0, 0, 1), 0.1);

            axesBrush = Brushes.Blue;
            DiffuseMaterial zAxisMaterial = new DiffuseMaterial(axesBrush);

            discreteZAxisModel = new GeometryModel3D(zMesh, zAxisMaterial);


            //X (normal: Z):
            Point3D zMax = new Point3D(b * Math.Cos(ToRadians(crystalCell.Gamma)), 0, b * Math.Sin(crystalCell.Gamma));

            xMesh.AddSegment(origin, zMax, new Vector3D(1, 1, 0), 0.1);

            Vector3D vZ = zMax - origin;

            vZ.Normalize();
            Vector3D perpZ = Vector3D.CrossProduct(vZ, new Vector3D(0, 1, 0));

            perpX.Normalize();
            Vector3D v1Z = ScaleVector(-vZ + perpZ, 1);
            Vector3D v2Z = ScaleVector(-vZ - perpZ, 1);

            xMesh.AddSegment(zMax, zMax + v1Z, new Vector3D(0, 1, 0), 0.1);
            xMesh.AddSegment(zMax, zMax + v2Z, new Vector3D(0, 1, 0), 0.1);

            Vector3D perpZ1 = Vector3D.CrossProduct(vZ, new Vector3D(1, 0, 0));

            perpX1.Normalize();
            Vector3D v1Z1 = ScaleVector(-vZ + perpZ1, 1);
            Vector3D v2Z1 = ScaleVector(-vZ - perpZ1, 1);

            xMesh.AddSegment(zMax, zMax + v1Z1, new Vector3D(1, 0, 0), 0.1);
            xMesh.AddSegment(zMax, zMax + v2Z1, new Vector3D(1, 0, 0), 0.1);

            axesBrush = Brushes.Red;
            DiffuseMaterial xAxisMaterial = new DiffuseMaterial(axesBrush);

            discreteXAxisModel = new GeometryModel3D(xMesh, xAxisMaterial);
        }