public void DrawBondLine(Wpg.WordprocessingGroup wordprocessingGroup, BondLine bl, string colour = "000000") { Point startPoint = new Point(bl.Start.X, bl.Start.Y); Point endPoint = new Point(bl.End.X, bl.End.Y); Rect cmlExtents = bl.BoundingBox; // Move Bond Line Extents and Points to have 0,0 Top Left Reference startPoint.Offset(-m_canvasExtents.Left, -m_canvasExtents.Top); endPoint.Offset(-m_canvasExtents.Left, -m_canvasExtents.Top); cmlExtents.Offset(-m_canvasExtents.Left, -m_canvasExtents.Top); // Move points into New Bond Line Extents startPoint.Offset(-cmlExtents.Left, -cmlExtents.Top); endPoint.Offset(-cmlExtents.Left, -cmlExtents.Top); switch (bl.Style) { case BondLineStyle.Solid: DrawSolidLine(wordprocessingGroup, cmlExtents, startPoint, endPoint); break; case BondLineStyle.Dotted: DrawDottedLine(wordprocessingGroup, cmlExtents, startPoint, endPoint, colour); break; case BondLineStyle.Dashed: DrawDashedLine(wordprocessingGroup, cmlExtents, startPoint, endPoint, colour); break; case BondLineStyle.Wavy: DrawWavyLine(wordprocessingGroup, cmlExtents, startPoint, endPoint); break; default: DrawSolidLine(wordprocessingGroup, cmlExtents, startPoint, endPoint); break; } }
public void DrawWedgeBond(Wpg.WordprocessingGroup wordprocessingGroup, BondLine bl) { BondLine leftBondLine = bl.GetParallel(BondOffset() / 2); BondLine rightBondLine = bl.GetParallel(-BondOffset() / 2); List <Point> points = new List <Point>(); points.Add(new Point(bl.Start.X, bl.Start.Y)); points.Add(new Point(leftBondLine.End.X, leftBondLine.End.Y)); points.Add(new Point(bl.End.X, bl.End.Y)); points.Add(new Point(rightBondLine.End.X, rightBondLine.End.Y)); Point wedgeStart = new Point(bl.Start.X, bl.Start.Y); Point wedgeEndLeft = new Point(leftBondLine.End.X, leftBondLine.End.Y); Point wedgeEndRight = new Point(rightBondLine.End.X, rightBondLine.End.Y); Point wedgeEndMiddle = new Point(bl.End.X, bl.End.Y); Bond thisBond = bl.Bond; Atom endAtom = thisBond.EndAtom; //Atom startAtom = thisBond.StartAtom; // EndAtom == C and Label is "" if (endAtom.Element as Element == Globals.PeriodicTable.C && thisBond.Rings.Count == 0 && string.IsNullOrEmpty(endAtom.SymbolText)) { // Has at least one other bond if (endAtom.Bonds.Count() > 1) { var otherBonds = endAtom.Bonds.Except(new[] { thisBond }).ToList(); bool allSingle = true; List <Bond> nonHydrogenBonds = new List <Bond>(); foreach (var otherBond in otherBonds) { if (!otherBond.Order.Equals(Globals.OrderSingle)) { allSingle = false; //break; } var otherAtom = otherBond.OtherAtom(endAtom); if (otherAtom.Element as Element != Globals.PeriodicTable.H) { nonHydrogenBonds.Add(otherBond); } } // All other bonds are single if (allSingle) { // Determine chamfer shape Vector left = (wedgeEndLeft - wedgeStart) * 2; Point leftEnd = wedgeStart + left; Vector right = (wedgeEndRight - wedgeStart) * 2; Point rightEnd = wedgeStart + right; bool canIntersect; bool intersect; Point intersection; Vector shortestLeft = left; Vector shortestRight = right; if (otherBonds.Count - nonHydrogenBonds.Count == 1) { otherBonds = nonHydrogenBonds; } if (otherBonds.Count == 1) { Bond bond = otherBonds[0]; Atom atom = bond.OtherAtom(endAtom); Vector vv = (endAtom.Position - atom.Position) * 2; Point otherEnd = atom.Position + vv; CoordinateTool.FindIntersection(wedgeStart, leftEnd, atom.Position, otherEnd, out canIntersect, out intersect, out intersection); if (intersect) { Vector v = intersection - wedgeStart; if (v.Length < shortestLeft.Length) { shortestLeft = v; } } CoordinateTool.FindIntersection(wedgeStart, rightEnd, atom.Position, otherEnd, out canIntersect, out intersect, out intersection); if (intersect) { Vector v = intersection - wedgeStart; if (v.Length < shortestRight.Length) { shortestRight = v; } } // Re-write list of points points = new List <Point>(); points.Add(wedgeStart); points.Add(wedgeStart + shortestLeft); points.Add(endAtom.Position); points.Add(wedgeStart + shortestRight); //DrawBondLine(wordprocessingGroup, new BondLine(BondLineStyle.Solid, wedgeEndMiddle, wedgeEndLeft, "ff0000")); //DrawBondLine(wordprocessingGroup, new BondLine(BondLineStyle.Solid, wedgeEndMiddle, wedgeEndRight, "ff0000")); } else { foreach (var bond in otherBonds) { CoordinateTool.FindIntersection(wedgeStart, leftEnd, bond.StartAtom.Position, bond.EndAtom.Position, out canIntersect, out intersect, out intersection); if (intersect) { Vector v = intersection - wedgeStart; if (v.Length < shortestLeft.Length) { shortestLeft = v; } } CoordinateTool.FindIntersection(wedgeStart, rightEnd, bond.StartAtom.Position, bond.EndAtom.Position, out canIntersect, out intersect, out intersection); if (intersect) { Vector v = intersection - wedgeStart; if (v.Length < shortestRight.Length) { shortestRight = v; } } } // Re-write list of points points = new List <Point>(); points.Add(wedgeStart); points.Add(wedgeStart + shortestLeft); points.Add(endAtom.Position); points.Add(wedgeStart + shortestRight); //DrawBondLine(wordprocessingGroup, new BondLine(BondLineStyle.Solid, wedgeEndMiddle, wedgeEndLeft, "ff0000")); //DrawBondLine(wordprocessingGroup, new BondLine(BondLineStyle.Solid, wedgeEndMiddle, wedgeEndRight, "ff0000")); } } } } switch (bl.Style) { case BondLineStyle.Wedge: DrawWedgeBond(wordprocessingGroup, points); break; case BondLineStyle.Hatch: DrawHatchBond(wordprocessingGroup, points); break; default: DrawBondLine(wordprocessingGroup, bl); break; } }
/// <summary> /// Creates the lines for a bond /// </summary> /// <param name="bond"></param> public void CreateLines(Bond bond) { IEnumerable <Ring> rings = bond.Rings; int ringCount = 0; foreach (Ring r in rings) { ringCount++; } Point bondStart = bond.StartAtom.Position; Point bondEnd = bond.EndAtom.Position; #region Create Bond Line objects switch (bond.Order) { case Globals.OrderZero: case "unknown": m_BondLines.Add(new BondLine(BondLineStyle.Dotted, bond)); break; case Globals.OrderPartial01: m_BondLines.Add(new BondLine(BondLineStyle.Dashed, bond)); break; case "1": case Globals.OrderSingle: switch (bond.Stereo) { case Globals.BondStereo.None: m_BondLines.Add(new BondLine(BondLineStyle.Solid, bond)); break; case Globals.BondStereo.Hatch: m_BondLines.Add(new BondLine(BondLineStyle.Hatch, bond)); break; case Globals.BondStereo.Wedge: m_BondLines.Add(new BondLine(BondLineStyle.Wedge, bond)); break; case Globals.BondStereo.Indeterminate: m_BondLines.Add(new BondLine(BondLineStyle.Wavy, bond)); break; default: m_BondLines.Add(new BondLine(BondLineStyle.Solid, bond)); break; } break; case Globals.OrderPartial12: case Globals.OrderAromatic: BondLine onePointFive; BondLine onePointFiveDotted; Point onePointFiveStart; Point onePointFiveEnd; switch (bond.Placement) { case Globals.BondDirection.Clockwise: onePointFive = new BondLine(BondLineStyle.Solid, bond); m_BondLines.Add(onePointFive); onePointFiveDotted = onePointFive.GetParallel(BondOffset()); onePointFiveStart = new Point(onePointFiveDotted.Start.X, onePointFiveDotted.Start.Y); onePointFiveEnd = new Point(onePointFiveDotted.End.X, onePointFiveDotted.End.Y); CoordinateTool.AdjustLineAboutMidpoint(ref onePointFiveStart, ref onePointFiveEnd, -(BondOffset() / 1.75)); onePointFiveDotted = new BondLine(BondLineStyle.Dotted, onePointFiveStart, onePointFiveEnd, bond); m_BondLines.Add(onePointFiveDotted); break; case Globals.BondDirection.Anticlockwise: onePointFive = new BondLine(BondLineStyle.Solid, bond); m_BondLines.Add(onePointFive); onePointFiveDotted = onePointFive.GetParallel(-BondOffset()); onePointFiveStart = new Point(onePointFiveDotted.Start.X, onePointFiveDotted.Start.Y); onePointFiveEnd = new Point(onePointFiveDotted.End.X, onePointFiveDotted.End.Y); CoordinateTool.AdjustLineAboutMidpoint(ref onePointFiveStart, ref onePointFiveEnd, -(BondOffset() / 1.75)); onePointFiveDotted = new BondLine(BondLineStyle.Dotted, onePointFiveStart, onePointFiveEnd, bond); m_BondLines.Add(onePointFiveDotted); break; case Globals.BondDirection.None: onePointFive = new BondLine(BondLineStyle.Solid, bond); m_BondLines.Add(onePointFive.GetParallel(-(BondOffset() / 2))); onePointFiveDotted = onePointFive.GetParallel(BondOffset() / 2); onePointFiveDotted.SetLineStyle(BondLineStyle.Dotted); m_BondLines.Add(onePointFiveDotted); break; } break; case "2": case Globals.OrderDouble: if (bond.Stereo == Globals.BondStereo.Indeterminate) //crossing bonds { // Crossed lines BondLine d = new BondLine(BondLineStyle.Solid, bondStart, bondEnd, bond); BondLine d1 = d.GetParallel(-(BondOffset() / 2)); BondLine d2 = d.GetParallel(BondOffset() / 2); m_BondLines.Add(new BondLine(BondLineStyle.Solid, new Point(d1.Start.X, d1.Start.Y), new Point(d2.End.X, d2.End.Y), bond)); m_BondLines.Add(new BondLine(BondLineStyle.Solid, new Point(d2.Start.X, d2.Start.Y), new Point(d1.End.X, d1.End.Y), bond)); } else { bool shifted = false; if (ringCount == 0) { if (bond.StartAtom.Element as Element == Globals.PeriodicTable.C && bond.EndAtom.Element as Element == Globals.PeriodicTable.C) { shifted = false; } else { shifted = true; } } if (bond.StartAtom.Degree == 1 | bond.EndAtom.Degree == 1) { shifted = true; } if (shifted) { BondLine d = new BondLine(BondLineStyle.Solid, bond); m_BondLines.Add(d.GetParallel(-(BondOffset() / 2))); m_BondLines.Add(d.GetParallel(BondOffset() / 2)); } else { Point outIntersectP1; Point outIntersectP2; bool linesIntersect; bool segmentsIntersect; Point centre; switch (bond.Placement) { case Globals.BondDirection.Anticlockwise: BondLine da = new BondLine(BondLineStyle.Solid, bond); m_BondLines.Add(da); BondLine bla = da.GetParallel(-BondOffset()); Point startPointa = bla.Start; Point endPointa = bla.End; if (bond.PrimaryRing != null) { centre = bond.PrimaryRing.Centroid.Value; // Diagnostics //m_BondLines.Add(new BondLine(bondStart, centre, BondLineStyle.Dotted, null)); //m_BondLines.Add(new BondLine(bondEnd, centre, BondLineStyle.Dotted, null)); CoordinateTool.FindIntersection(startPointa, endPointa, bondStart, centre, out linesIntersect, out segmentsIntersect, out outIntersectP1); CoordinateTool.FindIntersection(startPointa, endPointa, bondEnd, centre, out linesIntersect, out segmentsIntersect, out outIntersectP2); m_BondLines.Add(new BondLine(BondLineStyle.Solid, outIntersectP1, outIntersectP2, bond)); } else { CoordinateTool.AdjustLineAboutMidpoint(ref startPointa, ref endPointa, -(BondOffset() / 1.75)); m_BondLines.Add(new BondLine(BondLineStyle.Solid, startPointa, endPointa, bond)); } break; case Globals.BondDirection.Clockwise: BondLine dc = new BondLine(BondLineStyle.Solid, bond); m_BondLines.Add(dc); BondLine blc = dc.GetParallel(BondOffset()); Point startPointc = blc.Start; Point endPointc = blc.End; if (bond.PrimaryRing != null) { centre = bond.PrimaryRing.Centroid.Value; // Diagnostics //m_BondLines.Add(new BondLine(bondStart, centre, BondLineStyle.Dotted, null)); //m_BondLines.Add(new BondLine(bondEnd, centre, BondLineStyle.Dotted, null)); CoordinateTool.FindIntersection(startPointc, endPointc, bondStart, centre, out linesIntersect, out segmentsIntersect, out outIntersectP1); CoordinateTool.FindIntersection(startPointc, endPointc, bondEnd, centre, out linesIntersect, out segmentsIntersect, out outIntersectP2); m_BondLines.Add(new BondLine(BondLineStyle.Solid, outIntersectP1, outIntersectP2, bond)); } else { CoordinateTool.AdjustLineAboutMidpoint(ref startPointc, ref endPointc, -(BondOffset() / 1.75)); m_BondLines.Add(new BondLine(BondLineStyle.Solid, startPointc, endPointc, bond)); } break; default: switch (bond.Stereo) { case Globals.BondStereo.Cis: BondLine dcc = new BondLine(BondLineStyle.Solid, bond); m_BondLines.Add(dcc); BondLine blnewc = dcc.GetParallel(BondOffset()); Point startPointn = blnewc.Start; Point endPointn = blnewc.End; CoordinateTool.AdjustLineAboutMidpoint(ref startPointn, ref endPointn, -(BondOffset() / 1.75)); m_BondLines.Add(new BondLine(BondLineStyle.Solid, startPointn, endPointn, bond)); break; case Globals.BondStereo.Trans: BondLine dtt = new BondLine(BondLineStyle.Solid, bond); m_BondLines.Add(dtt); BondLine blnewt = dtt.GetParallel(BondOffset()); Point startPointt = blnewt.Start; Point endPointt = blnewt.End; CoordinateTool.AdjustLineAboutMidpoint(ref startPointt, ref endPointt, -(BondOffset() / 1.75)); m_BondLines.Add(new BondLine(BondLineStyle.Solid, startPointt, endPointt, bond)); break; default: BondLine dp = new BondLine(BondLineStyle.Solid, bond); m_BondLines.Add(dp.GetParallel(-(BondOffset() / 2))); m_BondLines.Add(dp.GetParallel(BondOffset() / 2)); break; } break; } } } break; case Globals.OrderPartial23: BondLine twoPointFive; BondLine twoPointFiveDotted; BondLine twoPointFiveParallel; Point twoPointFiveStart; Point twoPointFiveEnd; switch (bond.Placement) { case Globals.BondDirection.Clockwise: // Central bond line twoPointFive = new BondLine(BondLineStyle.Solid, bond); m_BondLines.Add(twoPointFive); // Solid bond line twoPointFiveParallel = twoPointFive.GetParallel(-BondOffset()); twoPointFiveStart = new Point(twoPointFiveParallel.Start.X, twoPointFiveParallel.Start.Y); twoPointFiveEnd = new Point(twoPointFiveParallel.End.X, twoPointFiveParallel.End.Y); CoordinateTool.AdjustLineAboutMidpoint(ref twoPointFiveStart, ref twoPointFiveEnd, -(BondOffset() / 1.75)); twoPointFiveParallel = new BondLine(BondLineStyle.Solid, twoPointFiveStart, twoPointFiveEnd, bond); m_BondLines.Add(twoPointFiveParallel); // Dotted bond line twoPointFiveDotted = twoPointFive.GetParallel(BondOffset()); twoPointFiveStart = new Point(twoPointFiveDotted.Start.X, twoPointFiveDotted.Start.Y); twoPointFiveEnd = new Point(twoPointFiveDotted.End.X, twoPointFiveDotted.End.Y); CoordinateTool.AdjustLineAboutMidpoint(ref twoPointFiveStart, ref twoPointFiveEnd, -(BondOffset() / 1.75)); twoPointFiveDotted = new BondLine(BondLineStyle.Dotted, twoPointFiveStart, twoPointFiveEnd, bond); m_BondLines.Add(twoPointFiveDotted); break; case Globals.BondDirection.Anticlockwise: // Central bond line twoPointFive = new BondLine(BondLineStyle.Solid, bond); m_BondLines.Add(twoPointFive); // Dotted bond line twoPointFiveDotted = twoPointFive.GetParallel(-BondOffset()); twoPointFiveStart = new Point(twoPointFiveDotted.Start.X, twoPointFiveDotted.Start.Y); twoPointFiveEnd = new Point(twoPointFiveDotted.End.X, twoPointFiveDotted.End.Y); CoordinateTool.AdjustLineAboutMidpoint(ref twoPointFiveStart, ref twoPointFiveEnd, -(BondOffset() / 1.75)); twoPointFiveDotted = new BondLine(BondLineStyle.Dotted, twoPointFiveStart, twoPointFiveEnd, bond); m_BondLines.Add(twoPointFiveDotted); // Solid bond line twoPointFiveParallel = twoPointFive.GetParallel(BondOffset()); twoPointFiveStart = new Point(twoPointFiveParallel.Start.X, twoPointFiveParallel.Start.Y); twoPointFiveEnd = new Point(twoPointFiveParallel.End.X, twoPointFiveParallel.End.Y); CoordinateTool.AdjustLineAboutMidpoint(ref twoPointFiveStart, ref twoPointFiveEnd, -(BondOffset() / 1.75)); twoPointFiveParallel = new BondLine(BondLineStyle.Solid, twoPointFiveStart, twoPointFiveEnd, bond); m_BondLines.Add(twoPointFiveParallel); break; case Globals.BondDirection.None: twoPointFive = new BondLine(BondLineStyle.Solid, bond); m_BondLines.Add(twoPointFive); m_BondLines.Add(twoPointFive.GetParallel(-BondOffset())); twoPointFiveDotted = twoPointFive.GetParallel(BondOffset()); twoPointFiveDotted.SetLineStyle(BondLineStyle.Dotted); m_BondLines.Add(twoPointFiveDotted); break; } break; case "3": case Globals.OrderTriple: BondLine tripple = new BondLine(BondLineStyle.Solid, bond); m_BondLines.Add(tripple); m_BondLines.Add(tripple.GetParallel(BondOffset())); m_BondLines.Add(tripple.GetParallel(-BondOffset())); break; default: // Draw a single line, so that there is something to see m_BondLines.Add(new BondLine(BondLineStyle.Solid, bond)); break; } #endregion Create Bond Line objects }