public Compound() { name = ""; atoms = new List <Atom>(); crystalCell = new CrystalCell(); dummy = false; }
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); }
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); }
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(); }
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); }
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)); } }
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); }
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); }
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); }