예제 #1
0
        /// <summary>
        /// Gets the geometry of a wedge bond.
        /// </summary>
        /// <param name="desc">WedgeBondDescriptor which is populated</param>
        /// <param name="standardBondLength">Standard bond length as defined by the model</param>
        /// <param name="standoff">Boundary width between atom label and bond terminus</param>
        public static void GetWedgeBondGeometry(WedgeBondLayout desc, double standardBondLength, double standoff)
        {
            //get the width of the wedge bond's thick end
            var bondVector = desc.PrincipleVector;
            var perpVector = bondVector.Perpendicular();

            perpVector.Normalize();
            perpVector *= standardBondLength * Globals.BondOffsetPercentage;

            // shrink the bond so it doesn't overlap any AtomVisuals
            AdjustTerminus(ref desc.Start, desc.End, desc.StartAtomHull, standoff);
            AdjustTerminus(ref desc.End, desc.Start, desc.EndAtomHull, standoff);

            //then draw it
            GetWedgePoints(desc, perpVector);
            //and pass it back as a Geometry
            StreamGeometry sg;

            sg = desc.GetOutline();
            sg.Freeze();
            desc.DefiningGeometry = sg;
        }
예제 #2
0
        /// <summary>
        /// Chamfers or forks the end of a wedge bond under special circumstances
        /// (one or more incoming single bonds)
        /// </summary>
        /// <param name="descriptor"> WedgeBondDescriptor to be populated</param>
        /// <param name="standardBondLength">Standard bond length as defined by the model</param>
        /// <param name="otherAtomPoints">List of positions of atoms splaying from the end atom</param>
        /// <param name="standoff"></param>
        public static void GetChamferedWedgeGeometry(WedgeBondLayout descriptor,
                                                     double standardBondLength,
                                                     List <Point> otherAtomPoints, double standoff)
        {
            var bondVector = descriptor.PrincipleVector;

            //first get an unaltered bond
            GetWedgeBondGeometry(descriptor, standardBondLength, standoff);

            var firstEdgeVector  = descriptor.FirstCorner - descriptor.Start;
            var secondEdgeVector = descriptor.SecondCorner - descriptor.Start;

            //get the two bonds with widest splay

            var widestPoints = from Point p in otherAtomPoints
                               orderby Math.Abs(Vector.AngleBetween(bondVector, p - descriptor.End)) descending
                               select p;

            //the scaling factors are what we multiply the bond edge vectors by
            double firstScalingFactor  = 0d;
            double secondScalingFactor = 0d;

            //work out the biggest scaling factor for either long edge
            foreach (var point in widestPoints)
            {
                BasicGeometry.IntersectLines(descriptor.Start,
                                             descriptor.FirstCorner,
                                             descriptor.End,
                                             point, out var firstEdgeCut, out var otherBond1Cut);
                BasicGeometry.IntersectLines(descriptor.Start,
                                             descriptor.SecondCorner,
                                             descriptor.End,
                                             point, out var secondEdgeCut, out var otherBond2Cut);
                if (otherAtomPoints.Count == 1)
                {
                    if (firstEdgeCut > firstScalingFactor)
                    {
                        firstScalingFactor = firstEdgeCut;
                    }
                    if (secondEdgeCut > secondScalingFactor)
                    {
                        secondScalingFactor = secondEdgeCut;
                    }
                }
                else
                {
                    if (firstEdgeCut > firstScalingFactor && otherBond1Cut < 1d && otherBond1Cut > 0d)
                    {
                        firstScalingFactor = firstEdgeCut;
                    }
                    if (secondEdgeCut > secondScalingFactor && otherBond2Cut < 1d && otherBond2Cut > 0d)
                    {
                        secondScalingFactor = secondEdgeCut;
                    }
                }
            }

            //and multiply the edges by the scaling factors
            descriptor.FirstCorner  = firstEdgeVector * firstScalingFactor + descriptor.Start;
            descriptor.SecondCorner = secondEdgeVector * secondScalingFactor + descriptor.Start;

            descriptor.CappedOff = true;

            var sg = descriptor.GetOutline();

            sg.Freeze();
            descriptor.DefiningGeometry = sg;
        }