示例#1
0
        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();
        }
示例#2
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);
                }
            }
        }
        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
        }
示例#4
0
        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));
        }
示例#5
0
        /// <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;
                    }
                }
            }
        }
示例#6
0
        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);
        }