コード例 #1
0
        private int GetRingSize(AtomVisual start, Point end, double bondSize)
        {
            //take the dot product of the distance we moved the mouse with the balancing vector

            double displacement = Vector.Multiply((end - start.Position), start.ParentAtom.BalancingVector());
            return GetRingSize(bondSize, displacement);
        }
コード例 #2
0
ファイル: DrawBehavior.cs プロジェクト: wiserwing/Version3
        private void ClearTemporaries()
        {
            if (_adorner != null)
            {
                RemoveAdorner(ref _adorner);
            }

            _currentAtomVisual = null;
            IsDrawing          = false;
            //clear this to prevent a weird bug in drawing
            CurrentEditor.ActiveChemistry = null;
        }
コード例 #3
0
        private void AtomAdded(Atom atom)
        {
            if (!chemicalVisuals.ContainsKey(atom)) //it's not already in the list
            {
                if (atom.Element is FunctionalGroup)
                {
                    chemicalVisuals[atom] = new FunctionalGroupVisual(atom, ShowAtomsInColour);
                }
                else
                {
                    chemicalVisuals[atom] = new AtomVisual(atom, ShowAtomsInColour, ShowImplicitHydrogens, ShowAllCarbonAtoms);
                }
            }

            var cv = chemicalVisuals[atom];

            if (cv is FunctionalGroupVisual fgv)
            {
                if (fgv.RefCount == 0) // it hasn't been added before
                {
                    fgv.ChemicalVisuals = chemicalVisuals;

                    fgv.BackgroundColor = Background;
                    fgv.SymbolSize      = ViewModel.SymbolSize;
                    fgv.SubscriptSize   = ViewModel.SymbolSize * ViewModel.ScriptScalingFactor;
                    fgv.SuperscriptSize = ViewModel.SymbolSize * ViewModel.ScriptScalingFactor;
                    fgv.Standoff        = ViewModel.Standoff;
                    fgv.Render();

                    AddVisual(fgv);
                }

                fgv.RefCount++;
            }
            else if (cv is AtomVisual av)
            {
                if (av.RefCount == 0) // it hasn't been added before
                {
                    av.ChemicalVisuals    = chemicalVisuals;
                    av.SymbolSize         = ViewModel.SymbolSize;
                    av.SubscriptSize      = ViewModel.SymbolSize * ViewModel.ScriptScalingFactor;
                    av.SuperscriptSize    = ViewModel.SymbolSize * ViewModel.ScriptScalingFactor;
                    av.BackgroundColor    = Background;
                    av.DisplayOverbonding = DisplayOverbondedAtoms;
                    av.Render();

                    AddVisual(av);
                }

                av.RefCount++;
            }
        }
コード例 #4
0
        private void AtomAdded(Atom atom)
        {
            if (!chemicalVisuals.ContainsKey(atom)) //it's not already in the list
            {
                if (atom.Element is FunctionalGroup fg)
                {
                    chemicalVisuals[atom] = new FunctionalGroupVisual(atom);
                }
                else
                {
                    chemicalVisuals[atom] = new AtomVisual(atom);
                }
            }

            var cv = chemicalVisuals[atom];

            if (cv is FunctionalGroupVisual fgv)
            {
                if (fgv.RefCount == 0) // it hasn't been added before
                {
                    fgv.ChemicalVisuals = chemicalVisuals;

                    fgv.BackgroundColor = Background;

                    fgv.Render();

                    AddVisual(fgv);
                }

                fgv.RefCount++;
            }
            else if (cv is AtomVisual av)
            {
                if (av.RefCount == 0) // it hasn't been added before
                {
                    av.ChemicalVisuals = chemicalVisuals;

                    av.BackgroundColor = Background;

                    av.Render();

                    AddVisual(av);
                }

                av.RefCount++;
            }
        }
コード例 #5
0
        private void CurrentEditor_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            var position = e.GetPosition(CurrentEditor);

            _currentAtomVisual = CurrentEditor.GetTargetedVisual(position) as AtomVisual;
            if (_currentAtomVisual == null)
            {
                _angleSnapper = new Snapper(position, EditViewModel);
            }
            else
            {
                Mouse.Capture(CurrentEditor);
                _angleSnapper   = new Snapper(_currentAtomVisual.ParentAtom.Position, EditViewModel);
                _lastAtomVisual = _currentAtomVisual;
            }
            IsDrawing = true;
        }
コード例 #6
0
        private void RedrawAtom(Atom atom)
        {
            int        refCount = 1;
            AtomVisual av       = null;

            if (chemicalVisuals.ContainsKey(atom))
            {
                av       = (AtomVisual)chemicalVisuals[atom];
                refCount = av.RefCount;
                AtomRemoved(atom);
            }

            AtomAdded(atom);

            av          = (AtomVisual)chemicalVisuals[atom];
            av.RefCount = refCount;
        }
コード例 #7
0
        /// <summary>
        /// tells you where to put a new atom
        /// </summary>
        /// <param name="lastAtomVisual"></param>
        /// <param name="congestedPositions">Places to avoid dumping the new atom</param>
        /// <returns></returns>
        private (Point NewPos, ClockDirections sproutDir) GetNewChainEndPos(AtomVisual lastAtomVisual)
        {
            ClockDirections GetGeneralDir(Vector bondVector)
            {
                double bondAngle = Vector.AngleBetween(BasicGeometry.ScreenNorth, bondVector);

                ClockDirections hour = (ClockDirections)BasicGeometry.SnapToClock(bondAngle);

                return(hour);
            }

            var    lastAtom = lastAtomVisual.ParentAtom;
            Vector newDirection;

            ClockDirections newTag;

            if (lastAtom.Degree == 0) //isolated atom
            {
                newDirection = ClockDirections.II.ToVector() * EditViewModel.Model.XamlBondLength;
                newTag       = ClockDirections.II;
            }
            else if (lastAtom.Degree == 1)
            {
                Vector bondVector = lastAtom.Position - lastAtom.Neighbours.First().Position;

                var hour = GetGeneralDir(bondVector);

                if (VirginAtom(lastAtom)) //it hasn't yet sprouted
                {
                    //Tag is used to store the direction the atom sprouted from its previous atom
                    newTag       = GetNewSproutDirection(hour);
                    newDirection = newTag.ToVector() * EditViewModel.Model.XamlBondLength;
                }
                else //it has sprouted, so where to put the new branch?
                {
                    var vecA = ((ClockDirections)lastAtom.Tag).ToVector();
                    vecA.Normalize();
                    var vecB = -bondVector;
                    vecB.Normalize();

                    var balancingVector = -(vecA + vecB);
                    balancingVector.Normalize();
                    newTag       = GetGeneralDir(balancingVector);
                    newDirection = balancingVector * EditViewModel.Model.XamlBondLength;
                }
            }
            else if (lastAtom.Degree == 2)
            {
                var balancingVector = lastAtom.BalancingVector();
                balancingVector.Normalize();
                newDirection = balancingVector * EditViewModel.Model.XamlBondLength;
                newTag       = GetGeneralDir(balancingVector);
            }
            else //lastAtom.Degree >= 2:  could get congested
            {
                FindOpenSpace(lastAtom, EditViewModel.Model.XamlBondLength, out newDirection);
                newTag = GetGeneralDir(newDirection);
            }

            return(newDirection + lastAtom.Position, newTag);
        }
コード例 #8
0
 public AtomHoverAdorner(UIElement adornedElement, AtomVisual targetedVisual) : this(adornedElement)
 {
     _targetedVisual = targetedVisual;
 }
コード例 #9
0
        private Geometry GetBondAdornerGeometry(Bond bond)
        {
            //work out the actual visible extent of the bond
            Point  startPoint, endPoint;
            Vector unitVector = bond.BondVector;

            unitVector.Normalize();

            AtomVisual startAtomVisual = CurrentEditor.GetAtomVisual(bond.StartAtom);
            AtomVisual endAtomVisual   = CurrentEditor.GetAtomVisual(bond.EndAtom);

            Point?sp;

            //work out where the bond vector intersects the start and end points of the bond
            if (!string.IsNullOrEmpty(bond.StartAtom.SymbolText) &&
                (sp = startAtomVisual.GetIntersection(bond.StartAtom.Position, bond.EndAtom.Position)) != null)
            {
                startPoint = sp.Value;
            }
            else
            {
                startPoint = bond.StartAtom.Position + unitVector * RenderRadius;
            }

            Point?ep;

            if (!string.IsNullOrEmpty(bond.EndAtom.SymbolText) &&
                (ep = endAtomVisual.GetIntersection(bond.StartAtom.Position, bond.EndAtom.Position)) != null)
            {
                endPoint = ep.Value;
            }
            else
            {
                endPoint = bond.EndAtom.Position - unitVector * RenderRadius;
            }

            //get the perpendiculars to the bond
            Matrix toLeft = new Matrix();

            toLeft.Rotate(-90);
            Matrix toRight = new Matrix();

            toRight.Rotate(90);

            Vector right = bond.BondVector * toRight;

            right.Normalize();
            Vector left = bond.BondVector * toLeft;

            left.Normalize();

            //draw the rectangle on top of the bond
            PathFigure pathFigure = new PathFigure();

            pathFigure.StartPoint = startPoint + right * RenderRadius;
            pathFigure.IsClosed   = true;

            LineSegment lineSegment1 = new LineSegment();

            lineSegment1.Point = startPoint + left * RenderRadius;
            pathFigure.Segments.Add(lineSegment1);

            LineSegment lineSegment2 = new LineSegment();

            lineSegment2.Point = endPoint + left * RenderRadius;
            pathFigure.Segments.Add(lineSegment2);

            LineSegment lineSegment3 = new LineSegment();

            lineSegment3.Point = endPoint + right * RenderRadius;
            pathFigure.Segments.Add(lineSegment3);

            //add in the figure
            List <PathFigure> figures = new List <PathFigure>();

            figures.Add(pathFigure);

            //now create the geometry
            PathGeometry pathGeometry = new PathGeometry(figures);

            //work out the end caps
            Geometry start = new EllipseGeometry(startPoint, RenderRadius, RenderRadius);
            Geometry end   = new EllipseGeometry(endPoint, RenderRadius, RenderRadius);

            //add them in
            CombinedGeometry result = new CombinedGeometry(GeometryCombineMode.Union, pathGeometry, start);

            result = new CombinedGeometry(GeometryCombineMode.Union, result, end);

            //and return
            return(result);
        }