public void DrawNRing(DrawingContext drawingContext, List <NewAtomPlacement> newPlacements) { StreamGeometry ringGeometry = new StreamGeometry(); if (_fixedRingAdorner.Unsaturated) //bit complicated as we have unsaturated bonds { using (var sgc = ringGeometry.Open()) { int newPlacementsCount = newPlacements.Count; var locations = (from p in newPlacements.ToArray().Reverse() select p.Position).ToArray(); HashSet <NewAtomPlacement> visited = new HashSet <NewAtomPlacement>(); Point?centroid = Geometry <Point> .GetCentroid(locations, p => p); var startAt = newPlacementsCount % 2; //place the double bonds in odd membered rings where they should start for (int i = startAt; i < newPlacementsCount + startAt; i++) { int firstIndex = i % newPlacementsCount; var oldAtomPlacement = newPlacements[firstIndex]; int secondIndex = (firstIndex + 1) % newPlacementsCount; var newAtomPlacement = newPlacements[secondIndex]; if (!visited.Contains(oldAtomPlacement) & !visited.Contains(newAtomPlacement) && !(oldAtomPlacement.ExistingAtom?.IsUnsaturated ?? false) && !(newAtomPlacement.ExistingAtom?.IsUnsaturated ?? false)) { List <Point> dummy = new List <Point>(); DoubleBondLayout dbd = new DoubleBondLayout { Start = oldAtomPlacement.Position, End = newAtomPlacement.Position, Placement = Globals.BondDirection.Anticlockwise, PrimaryCentroid = centroid }; BondGeometry.GetDoubleBondGeometry(dbd, dbd.PrincipleVector.Length); BasicGeometry.DrawGeometry(sgc, dbd.DefiningGeometry); visited.Add(oldAtomPlacement); visited.Add(newAtomPlacement); } else { BondLayout sbd = new BondLayout { Start = oldAtomPlacement.Position, End = newAtomPlacement.Position }; BondGeometry.GetSingleBondGeometry(sbd); BasicGeometry.DrawGeometry(sgc, sbd.DefiningGeometry); } oldAtomPlacement = newAtomPlacement; } sgc.Close(); } drawingContext.DrawGeometry(null, _fixedRingAdorner.BondPen, ringGeometry); } else //saturated ring, just draw a polygon { drawingContext.DrawGeometry(null, _fixedRingAdorner.BondPen, BasicGeometry.BuildPolyPath(_fixedRingAdorner.Placements, true)); } }
public BondLayout GetBondLayout(Point startPoint, Point endPoint, double bondLength, Globals.BondStereo stereo, string order, Ring existingRing = null, Ring subsidiaryRing = null) { BondLayout descriptor = null; //check to see if it's a wedge or a hatch yet if (stereo == Globals.BondStereo.Wedge || stereo == Globals.BondStereo.Hatch) { var wbd = new WedgeBondLayout { Start = startPoint, End = endPoint }; BondGeometry.GetWedgeBondGeometry(wbd, bondLength, CurrentEditor.ViewModel.Standoff); return(wbd); } if (stereo == Globals.BondStereo.Indeterminate && (order == Globals.OrderSingle)) { descriptor = new BondLayout { Start = startPoint, End = endPoint }; BondGeometry.GetWavyBondGeometry(descriptor, bondLength, CurrentEditor.ViewModel.Standoff); return(descriptor); } var ordervalue = Bond.OrderToOrderValue(order); //single or dotted bond if (ordervalue <= 1) { descriptor = new BondLayout { Start = startPoint, End = endPoint }; BondGeometry.GetSingleBondGeometry(descriptor, CurrentEditor.ViewModel.Standoff); } //double bond if (ordervalue == 2 || ordervalue == 1.5) { DoubleBondLayout dbd = new DoubleBondLayout { Start = startPoint, End = endPoint }; if (stereo == Globals.BondStereo.Indeterminate) { BondGeometry.GetCrossedDoubleGeometry(dbd, bondLength, CurrentEditor.ViewModel.Standoff); } else { dbd.PrimaryCentroid = existingRing?.Centroid; dbd.SecondaryCentroid = subsidiaryRing?.Centroid; BondGeometry.GetDoubleBondGeometry(dbd, bondLength, CurrentEditor.ViewModel.Standoff); } descriptor = dbd; } //tripe bond if (ordervalue == 2.5 || ordervalue == 3) { var tbd = new TripleBondLayout { Start = startPoint, End = endPoint }; BondGeometry.GetTripleBondGeometry(tbd, bondLength, CurrentEditor.ViewModel.Standoff); descriptor = tbd; } return(descriptor); }