Example #1
0
        private void BeautifyLines(Atom atom, string bondId)
        {
            if ((Element)atom.Element == Globals.PeriodicTable.C)
            {
                if (atom.Bonds.Count == 3)
                {
                    bool            isInRing = atom.Rings.Count != 0;
                    List <BondLine> lines    = _bondLines.Where(bl => bl.ParentBond.Equals(bondId)).ToList();
                    if (lines.Any())
                    {
                        List <Bond> otherBonds;
                        if (isInRing)
                        {
                            otherBonds = atom.Bonds.Where(b => !b.Id.Equals(bondId)).ToList();
                        }
                        else
                        {
                            otherBonds = atom.Bonds.Where(b => !b.Id.Equals(bondId) && b.OrderValue == 1).ToList();
                        }

                        if (lines.Count == 2 && otherBonds.Count == 2)
                        {
                            BondLine line1 = _bondLines.First(bl => bl.ParentBond.Equals(otherBonds[0].Id));
                            BondLine line2 = _bondLines.First(bl => bl.ParentBond.Equals(otherBonds[1].Id));
                            TrimLines(lines, line1, line2, isInRing);
                        }
                    }
                }
            }
        }
Example #2
0
 private void TrimLines(List <BondLine> mainPair, BondLine line1, BondLine line2, bool isInRing)
 {
     // Only two of these calls are expected to do anything
     if (!TrimLine(mainPair[0], line1, isInRing))
     {
         TrimLine(mainPair[0], line2, isInRing);
     }
     if (!TrimLine(mainPair[1], line1, isInRing))
     {
         TrimLine(mainPair[1], line2, isInRing);
     }
 }
Example #3
0
        private bool TrimLine(BondLine leftOrRight, BondLine line, bool isInRing)
        {
            bool  dummy;
            bool  intersect;
            Point intersection;

            // Make a longer version of the line
            Point startLonger = new Point(leftOrRight.Start.X, leftOrRight.Start.Y);
            Point endLonger   = new Point(leftOrRight.End.X, leftOrRight.End.Y);

            CoordinateTool.AdjustLineAboutMidpoint(ref startLonger, ref endLonger, _medianBondLength / 5);

            // See if they intersect at one end
            CoordinateTool.FindIntersection(startLonger, endLonger, line.Start, line.End,
                                            out dummy, out intersect, out intersection);

            // If they intersect update the main line
            if (intersect)
            {
                double l1 = CoordinateTool.DistanceBetween(intersection, leftOrRight.Start);
                double l2 = CoordinateTool.DistanceBetween(intersection, leftOrRight.End);
                if (l1 > l2)
                {
                    leftOrRight.End = new Point(intersection.X, intersection.Y);
                }
                else
                {
                    leftOrRight.Start = new Point(intersection.X, intersection.Y);
                }
                if (!isInRing)
                {
                    l1 = CoordinateTool.DistanceBetween(intersection, line.Start);
                    l2 = CoordinateTool.DistanceBetween(intersection, line.End);
                    if (l1 > l2)
                    {
                        line.End = new Point(intersection.X, intersection.Y);
                    }
                    else
                    {
                        line.Start = new Point(intersection.X, intersection.Y);
                    }
                }
            }

            return(intersect);
        }
Example #4
0
        private void ShrinkBondLinesPass2(Progress pb)
        {
            // so that they do not overlap label characters

            if (_atomLabelCharacters.Count > 1)
            {
                pb.Show();
            }
            pb.Message = "Clipping Bond Lines - Pass 2";
            pb.Value   = 0;
            pb.Maximum = _atomLabelCharacters.Count;

            foreach (AtomLabelCharacter alc in _atomLabelCharacters)
            {
                pb.Increment(1);

                double width  = OoXmlHelper.ScaleCsTtfToCml(alc.Character.Width);
                double height = OoXmlHelper.ScaleCsTtfToCml(alc.Character.Height);

                if (alc.IsSubScript)
                {
                    // Shrink bounding box
                    width  = width * OoXmlHelper.SUBSCRIPT_SCALE_FACTOR;
                    height = height * OoXmlHelper.SUBSCRIPT_SCALE_FACTOR;
                }

                // Create rectangle of the bounding box with a suitable clipping margin
                Rect cbb = new Rect(alc.Position.X - OoXmlHelper.CHARACTER_CLIPPING_MARGIN,
                                    alc.Position.Y - OoXmlHelper.CHARACTER_CLIPPING_MARGIN,
                                    width + (OoXmlHelper.CHARACTER_CLIPPING_MARGIN * 2),
                                    height + (OoXmlHelper.CHARACTER_CLIPPING_MARGIN * 2));

                //Debug.WriteLine("Character: " + alc.Ascii + " Rectangle: " + a);

                // Just in case we end up splitting a line into two
                List <BondLine> extraBondLines = new List <BondLine>();

                // Select Lines which may require trimming
                // By using LINQ to implement the following SQL
                // Where (L.Right Between Cbb.Left And Cbb.Right)
                //    Or (L.Left Between Cbb.Left And Cbb.Right)
                //    Or (L.Top Between Cbb.Top And Cbb.Botton)
                //    Or (L.Bottom Between Cbb.Top And Cbb.Botton)

                var targeted = from l in _bondLines
                               where (cbb.Left <= l.BoundingBox.Right & l.BoundingBox.Right <= cbb.Right)
                               | (cbb.Left <= l.BoundingBox.Left & l.BoundingBox.Left <= cbb.Right)
                               | (cbb.Top <= l.BoundingBox.Top & l.BoundingBox.Top <= cbb.Bottom)
                               | (cbb.Top <= l.BoundingBox.Bottom & l.BoundingBox.Bottom <= cbb.Bottom)
                               select l;

                foreach (BondLine bl in targeted)
                {
                    //pb.Increment(1);

                    Point start = new Point(bl.Start.X, bl.Start.Y);
                    Point end   = new Point(bl.End.X, bl.End.Y);

                    //Debug.WriteLine("  Line From: " + start + " To: " + end);

                    int attempts = 0;
                    if (CohenSutherland.ClipLine(cbb, ref start, ref end, out attempts))
                    {
                        //Debug.WriteLine("    Clipped Line Start Point: " + start);
                        //Debug.WriteLine("    Clipped Line   End Point: " + end);

                        bool bClipped = false;

                        if (Math.Abs(bl.Start.X - start.X) < EPSILON && Math.Abs(bl.Start.Y - start.Y) < EPSILON)
                        {
                            bl.Start = new Point(end.X, end.Y);
                            bClipped = true;
                        }
                        if (Math.Abs(bl.End.X - end.X) < EPSILON && Math.Abs(bl.End.Y - end.Y) < EPSILON)
                        {
                            bl.End   = new Point(start.X, start.Y);
                            bClipped = true;
                        }

                        if (!bClipped)
                        {
                            // Line was clipped at both ends;
                            // 1. Generate new line
                            BondLine extraLine = new BondLine(new Point(end.X, end.Y), new Point(bl.End.X, bl.End.Y), bl.Type, bl.ParentBond, bl.ParentMolecule, bl.StartAtomId, bl.EndAtomId);
                            extraBondLines.Add(extraLine);
                            // 2. Trim existing line
                            bl.End = new Point(start.X, start.Y);
                        }
                    }
                    if (attempts >= 15)
                    {
                        Debug.WriteLine("Clipping failed !");
                    }
                }

                // Add any extra lines generated by this character into the List of Bond Lines
                foreach (BondLine bl in extraBondLines)
                {
                    _bondLines.Add(bl);
                }
            }
        }
Example #5
0
        public void DrawBondLines(Graphics g)
        {
            List <Bond> starts = new List <Bond>();

            foreach (Bond b in drawnBonds)
            {
                if (b.ChainType != ChainType.None && b.IsStart)
                {
                    starts.Add(b);
                }
            }

            foreach (Bond start in starts)
            {
                if (start.ChainType.IsDistributed())
                {
                    Bond curBond = start;
                    while (curBond.Next != null)
                    {
                        Bond     nextBond = curBond.Next;
                        PointF   p0       = bondPoints[curBond.GetHandleHash(curBond.ChainType.GetOppositeAttachment())];
                        PointF   p1       = bondPoints[nextBond.GetHandleHash()];
                        float    difX     = p1.X - p0.X;
                        float    difY     = p1.Y - p0.Y;
                        float    dist     = (float)Math.Sqrt(difX * difX + difY * difY);
                        float    normX    = difX * (1f / dist) * 5;
                        float    normY    = difY * (1f / dist) * 5;
                        PointF[] pts      = new PointF[squiggleCount + 1];
                        pts[0] = p0;
                        pts[pts.Length - 1] = p1;
                        for (int i = 1; i < pts.Length - 1; i++)
                        {
                            int sign = i % 2 == 0 ? 1 : -1;
                            pts[i] = new PointF(
                                p0.X + difX * i / squiggleCount + normY * sign,
                                p0.Y + difY * i / squiggleCount + normX * sign);
                        }
                        PointF midPoint = p0.MidPoint(p1);
                        //g.DrawLine(Pens.Green, p0, p1);
                        g.DrawCurve(Pens.Green, pts);
                        curBond = nextBond;
                    }
                }
                else if (start.ChainType.IsAligned())
                {
                    Bond curBond  = start;
                    Bond lastBond = curBond.GetLast();

                    PointF   pStart = bondPoints[curBond.GetHandleHash()];
                    PointF   pEnd   = bondPoints[lastBond.GetHandleHash()];
                    BondLine bl     = new BondLine(pStart, pEnd, curBond.BondType, curBond.SourceAttachment);

                    do
                    {
                        PointF p0 = bondPoints[curBond.GetHandleHash()];

                        float  xb  = p0.X + bl.offset.X;
                        float  yb  = p0.Y + bl.offset.Y;
                        PointF p0b = new PointF(xb, yb);
                        g.DrawLine(Pens.Red, p0, p0b);

                        curBond = curBond.Next;
                    }while (curBond != null && !curBond.IsStart);

                    // joining line
                    g.DrawLine(
                        Pens.Red,
                        pStart.X + bl.offset.X,
                        pStart.Y + bl.offset.Y,
                        pEnd.X + bl.offset.X,
                        pEnd.Y + bl.offset.Y);
                }
            }

            drawnBonds.Clear();
            bondLines.Clear();
            bondPoints.Clear();
        }