private void btnClipLines_Click(object sender, EventArgs e) { var newLines = new List <Tuple <PointF, PointF> >(); foreach (var line in _lines) { var p1 = line.Item1; var p2 = line.Item2; var clipped = CohenSutherland.ClipSegment(_bounds, p1, p2); if (clipped != null) { newLines.Add(clipped); } } _lines = newLines; splitContainer1.Panel2.Invalidate(); }
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); } } }
public void StRayAlgo()//straight ray algorithm { if (_result.Count == 0) { _result.Clear(); } int n_d = _initialDiffusivity.Count; //he number of cells, it equals the number of columns of matrix A int n_t = _tProcessed.Count; //the number of travel times, it equals the number of rows of matrix A // b=Ax, x->x2 // consider b as time, A as distance, x as speed double xMax = 1.0 / (Math.Sqrt(_iP.MinD)); // set the constraint, the max of x, x=1/(root of diffusivity) double xMin = 1.0 / (Math.Sqrt(_iP.MaxD)); // set the constraint, the min of x, x=1/(root of diffusivity) List <double> estimatedD = _initialDiffusivity.ToList(); Vector <double> x = Vector <double> .Build.Dense(n_d, 1); for (int i = 0; i < n_d; i++) { x[i] = 1.0 / (Math.Sqrt(estimatedD[i]));//the speed vector, x=1/(root of diffusivity) } #region int iter = 0; double RMS = _iP.CriRMS + 1; while (iter <_iP.StrRay& RMS> _iP.CriRMS) { //STEP 1 SIRT_Result_StraightRay Record = new SIRT_Result_StraightRay(); Record.Iter = iter; Record.OldProcessedD = x.ToList(); //==================================================== //STEP 2 : Set matrix A Matrix <double> A = Matrix <double> .Build.Dense(n_t, n_d, 0); for (int row = 0; row < n_t; row++) { Inv_SRInfoLine infoLine = (Inv_SRInfoLine)_table.SRInfoLineList[row]; MathNet.Spatial.Euclidean.Point2D PStart = new MathNet.Spatial.Euclidean.Point2D(infoLine.Start.Coor[0], infoLine.Start.Coor[2]); MathNet.Spatial.Euclidean.Point2D PEnd = new MathNet.Spatial.Euclidean.Point2D(infoLine.End.Coor[0], infoLine.End.Coor[2]); MathNet.Spatial.Euclidean.Line2D Traj = new MathNet.Spatial.Euclidean.Line2D(PStart, PEnd); for (int col = 0; col < n_d; col++) { CohenSutherland coh = new CohenSutherland(); List <MathNet.Spatial.Euclidean.Point2D> Ps = coh.CohenSutherlandLineClip(_fRs[col], PStart, PEnd).ToList(); if (Ps.Count > 1) { A[row, col] = Ps[0].DistanceTo(Ps[1]); } } } Record.A = A.Clone(); Record.ProcessedTime = (A * x).ToList(); //==================================================== //STEP 3 : set the start node and the end node from Record foreach (object obj in _table.SRInfoLineList) { Inv_SRInfoLine infoLine = (Inv_SRInfoLine)obj; Record.Start.Add(infoLine.Start); Record.End.Add(infoLine.End); } //==================================================== //STEP 4 : cimmino calculation Vector <double> b = Vector <double> .Build.DenseOfArray(_tProcessed.ToArray()); SIRT_Options so = new SIRT_Options(b, A, x, 1);// b=Ax Vector <double> x2 = so.XUpdaterDROP(x, 1); //==================================================== //STEP 7 : update x and diffusivity for next iteration x = x2.Clone(); for (int i = 0; i < n_d; i++) { if (x[i] < conMinX[i]) { x[i] = conMinX[i]; } if (x[i] > conMaxX[i]) { x[i] = conMaxX[i]; } } Record.NewProcessedD = x.ToList(); //==================================================== _result.Add(Record);//output iter = iter + 1; } #endregion }
public Tuple <PointF, PointF> GetClippedEnds(Rectangle bounds) { Site vertex0, vertex1; var xmin = bounds.X; var ymin = bounds.Y; var xmax = bounds.Right; var ymax = bounds.Bottom; float x0, x1, y0, y1; if (Math.Abs(A - 1.0) < Double.Epsilon && B >= 0.0) { vertex0 = RightVertex; vertex1 = LeftVertex; } else { vertex0 = LeftVertex; vertex1 = RightVertex; } if (Math.Abs(A - 1.0) < Double.Epsilon) { y0 = ymin; if (vertex0 != null && vertex0.Y > ymin) { y0 = vertex0.Y; } if (y0 > ymax) { return(null); } x0 = C - B * y0; y1 = ymax; if (vertex1 != null && vertex1.Y < ymax) { y1 = vertex1.Y; } if (y1 < ymin) { return(null); } x1 = C - B * y1; if ((x0 > xmax && x1 > xmax) || (x0 < xmin && x1 < xmin)) { return(null); } if (x0 > xmax) { x0 = xmax; y0 = (C - x0) / B; } else if (x0 < xmin) { x0 = xmin; y0 = (C - x0) / B; } if (x1 > xmax) { x1 = xmax; y1 = (C - x1) / B; } else if (x1 < xmin) { x1 = xmin; y1 = (C - x1) / B; } } else { x0 = xmin; if (vertex0 != null && vertex0.X > xmin) { x0 = vertex0.X; } if (x0 > xmax) { return(null); } y0 = C - A * x0; x1 = xmax; if (vertex1 != null && vertex1.X < xmax) { x1 = vertex1.X; } if (x1 < xmin) { return(null); } y1 = C - A * x1; if ((y0 > ymax && y1 > ymax) || (y0 < ymin && y1 < ymin)) { return(null); } if (y0 > ymax) { y0 = ymax; x0 = (C - y0) / A; } else if (y0 < ymin) { y0 = ymin; x0 = (C - y0) / A; } if (y1 > ymax) { y1 = ymax; x1 = (C - y1) / A; } else if (y1 < ymin) { y1 = ymin; x1 = (C - y1) / A; } } var clipped = CohenSutherland.ClipSegment(bounds, new PointF(x0, y0), new PointF(x1, y1)); //Console.WriteLine("cl {0} {1} {2} {3}", x0, y0, x1, y1); return((vertex0 == LeftVertex) ? new Tuple <PointF, PointF>(clipped.Item1, clipped.Item2) : new Tuple <PointF, PointF>(clipped.Item2, clipped.Item1)); }
/// <summary> /// 切割矢量并输出成bitmap /// </summary> /// <param name="featureCollection"></param> /// <param name="outputDir"></param> public void Output(FeatureCollection featureCollection, string outputDir) { var _tileDictionary = _vectorPyramid.TileDictionary; int _tileSize = _vectorPyramid.Projection.TileSize; // foreach (int zoom in _tileDictionary.Keys) { var tileCollection = _tileDictionary[zoom]; foreach (var tile in tileCollection) { try { // Bitmap bmp = new Bitmap(_tileSize, _tileSize); Graphics g = Graphics.FromImage(bmp); Pen pen = new Pen(Color.Black, 3); // for (int i = 0; i < featureCollection.Count; i++) { IFeature f = featureCollection[i]; //点 if (f.Geometry.OgcGeometryType == OgcGeometryType.Point) { Coordinate point = f.Geometry.Coordinate; if (tile.Bound.PointInPolygon(point)) { //2.2.1 计算点的像素坐标 Coordinate pixel = _vectorPyramid.Projection.LatlngToPoint(point, zoom); // double deltaX = pixel.X / _tileSize - tile.X; double deltaY = pixel.Y / _tileSize - tile.Y; int x = Convert.ToInt32(deltaX * _tileSize); int y = Convert.ToInt32(deltaY * _tileSize); g.DrawLine(pen, x, x, x, y); } continue; } //线 else if (f.Geometry.OgcGeometryType == OgcGeometryType.LineString) { //2.1瓦片裁剪道路 List <Coordinate> clipLine = CohenSutherland.GetIntersectedPolyline(f.Geometry.Coordinates, tile.Bound); if (clipLine.Count == 0) { continue; } int x0 = -1000, y0 = -1000; //2.2 绘制clipLine foreach (Coordinate point in clipLine) { //2.2.1 计算点的像素坐标 Coordinate pixel = _vectorPyramid.Projection.LatlngToPoint(point, zoom); // double deltaX = pixel.X / _tileSize - tile.X; double deltaY = pixel.Y / _tileSize - tile.Y; int x = Convert.ToInt32(deltaX * _tileSize); int y = Convert.ToInt32(deltaY * _tileSize); if (x0 == -1000 && y0 == -1000) { x0 = x; y0 = y; continue; } else { g.DrawLine(pen, x0, y0, x, y); x0 = x; y0 = y; } } } //面 else if (f.Geometry.OgcGeometryType == OgcGeometryType.Polygon) { List <Coordinate> clipPolygon = SutherlandHodgman.GetIntersectedPolygon(f.Geometry.Coordinates, tile.Bound); if (clipPolygon.Count < 3) { continue; } int x0 = -1000, y0 = -1000; //2.2 绘制clipLine foreach (Coordinate point in clipPolygon) { //2.2.1 计算点的像素坐标 Coordinate pixel = _vectorPyramid.Projection.LatlngToPoint(point, zoom); // double deltaX = pixel.X / _tileSize - tile.X; double deltaY = pixel.Y / _tileSize - tile.Y; int x = Convert.ToInt32(deltaX * _tileSize); int y = Convert.ToInt32(deltaY * _tileSize); if (x0 == -1000 && y0 == -1000) { x0 = x; y0 = y; continue; } else { g.DrawLine(pen, x0, y0, x, y); x0 = x; y0 = y; } } } } //2.3 保存bmp到指定路径 if (!System.IO.Directory.Exists(outputDir + @"\" + zoom)) { System.IO.Directory.CreateDirectory(outputDir + @"\" + zoom); } //根据geometry id存储,获取不到geometry的id,所以只能自定内部序号 bmp.Save(outputDir + @"\" + zoom + @"\" + tile.X + "_" + tile.Y + "_" + tile.Z + ".jpg"); } catch { continue; } } } }
protected override bool OnExposeEvent(Gdk.EventExpose args) { #if SYSTEM_DRAWING drawer = new SystemDrawer(GdkWindow, Antialias); #else if (!Antialias && !PlatformDetection.IsMac) { drawer = new GdkDrawer(GdkWindow); } else { drawer = new CairoDrawer(GdkWindow, Antialias); } #endif drawer.Clear(backgroundColor); if (Grid.Visible) { DrawGrid(); } if (Level != null) { // clipping area to Map int Left, Right, Top, Bottom; Left = Transform.ToMapX(args.Area.X); Right = Transform.ToMapX(args.Area.Width + args.Area.X); Top = Transform.ToMapY(args.Area.Y); Bottom = Transform.ToMapY(args.Area.Height + args.Area.Y); CohenSutherland[] Points = new CohenSutherland[Level.Endpoints.Count]; for (short i = 0; i < Level.Endpoints.Count; ++i) { Point p = Level.Endpoints[i]; Points[i] = CohenSutherland.Inside; if (p.X < Left) { Points[i] |= CohenSutherland.Left; } else if (p.X > Right) { Points[i] |= CohenSutherland.Right; } if (p.Y < Top) { Points[i] |= CohenSutherland.Top; } else if (p.Y > Bottom) { Points[i] |= CohenSutherland.Bottom; } } for (int i = 0; i < Level.Polygons.Count; ++i) { Polygon polygon = Level.Polygons[i]; CohenSutherland code = ~CohenSutherland.Inside; for (short v = 0; v < polygon.VertexCount; ++v) { code &= Points[polygon.EndpointIndexes[v]]; } if (code == CohenSutherland.Inside && Filter(polygon)) { DrawPolygon((short)i, PolygonColor.Normal); } } if (Selection.Polygon != -1) { Polygon polygon = Level.Polygons[Selection.Polygon]; CohenSutherland code = ~CohenSutherland.Inside; if (Filter(polygon)) { for (short i = 0; i < polygon.VertexCount; ++i) { code &= Points[polygon.EndpointIndexes[i]]; } if (code == CohenSutherland.Inside) { DrawPolygon(Selection.Polygon, PolygonColor.Selected); } } if (polygon.Type == PolygonType.Teleporter && polygon.Permutation >= 0 && polygon.Permutation < Level.Polygons.Count) { Polygon destination = Level.Polygons[polygon.Permutation]; if (Filter(destination)) { code = ~CohenSutherland.Inside; for (short i = 0; i < destination.VertexCount; ++i) { code &= Points[destination.EndpointIndexes[i]]; } if (code == CohenSutherland.Inside) { DrawPolygon(polygon.Permutation, PolygonColor.Destination); } } } } Line selectedLine = null; if (Selection.Line != -1) { selectedLine = Level.Lines[Selection.Line]; } foreach (Line line in Level.Lines) { if ((Points[line.EndpointIndexes[0]] & Points[line.EndpointIndexes[1]]) == CohenSutherland.Inside && line != selectedLine) { if (Level.FilterLine(Filter, line)) { DrawLine(line); } } } if (selectedLine != null) { DrawLine(selectedLine); } for (short i = 0; i < Level.Endpoints.Count; ++i) { if (Level.FilterPoint(Filter, i) && Points[i] == CohenSutherland.Inside) { DrawPoint(Level.Endpoints[i]); } } Annotation selectedAnnotation = null; if (Selection.Annotation != -1) { selectedAnnotation = Level.Annotations[Selection.Annotation]; } if (Mode == DrawMode.Draw) { foreach (Annotation note in Level.Annotations) { if (note.PolygonIndex == -1 || Filter(Level.Polygons[note.PolygonIndex])) { DrawAnnotation(note, note == selectedAnnotation); } } int ObjectSize = (int)(16 / 2 / Transform.Scale); MapObject selectedObj = null; if (Selection.Object != -1) { selectedObj = Level.Objects[Selection.Object]; } foreach (MapObject obj in Level.Objects) { if (obj != selectedObj && obj.X > Left - ObjectSize && obj.X < Right + ObjectSize && obj.Y > Top - ObjectSize && obj.Y < Bottom + ObjectSize) { if (obj.PolygonIndex == -1 || Filter(Level.Polygons[obj.PolygonIndex])) { DrawObject(obj, false); } } } if (selectedObj != null && selectedObj.X > Left - ObjectSize && selectedObj.X < Right + ObjectSize && selectedObj.Y > Top - ObjectSize && selectedObj.Y < Bottom + ObjectSize) { if (selectedObj.PolygonIndex == -1 || Filter(Level.Polygons[selectedObj.PolygonIndex])) { DrawObject(selectedObj, true); } } } if (Level.TemporaryLineStartIndex != -1) { // draw the temporarily drawn line drawer.DrawLine(selectedLineColor, Transform.ToScreenPoint(Level.Endpoints[Level.TemporaryLineStartIndex]), Transform.ToScreenPoint(Level.TemporaryLineEnd)); } if (Selection.Point != -1) { // draw the selected point DrawFatPoint(selectedLineColor, Level.Endpoints[Selection.Point]); } } drawer.Dispose(); return(true); }