コード例 #1
0
        private double CalSimilarity(List <CCorrCpts> pCorrCptsLt)
        {
            //数据准备
            //X、Y的差值
            double[] dblFrDiffX = new double[pCorrCptsLt.Count - 1];
            double[] dblFrDiffY = new double[pCorrCptsLt.Count - 1];
            double[] dblToDiffX = new double[pCorrCptsLt.Count - 1];
            double[] dblToDiffY = new double[pCorrCptsLt.Count - 1];
            for (int i = 0; i < pCorrCptsLt.Count - 1; i++)
            {
                dblFrDiffX[i] = pCorrCptsLt[i + 1].FrCpt.X - pCorrCptsLt[i].FrCpt.X;
                dblFrDiffY[i] = pCorrCptsLt[i + 1].FrCpt.Y - pCorrCptsLt[i].FrCpt.Y;
                dblToDiffX[i] = pCorrCptsLt[i + 1].ToCpt.X - pCorrCptsLt[i].ToCpt.X;
                dblToDiffY[i] = pCorrCptsLt[i + 1].ToCpt.Y - pCorrCptsLt[i].ToCpt.Y;
            }
            //各线段长度
            double[] dblFrDis = new double[pCorrCptsLt.Count - 1];
            double[] dblToDis = new double[pCorrCptsLt.Count - 1];
            for (int i = 0; i < pCorrCptsLt.Count - 1; i++)
            {
                dblFrDis[i] = Math.Sqrt(dblFrDiffX[i] * dblFrDiffX[i] + dblFrDiffY[i] * dblFrDiffY[i]);
                dblToDis[i] = Math.Sqrt(dblToDiffX[i] * dblToDiffX[i] + dblToDiffY[i] * dblToDiffY[i]);
            }
            //Fr线段和To线段之间的角度差(设定为必然小于180度,用余弦求)
            double[] dblDiffAngle = new double[pCorrCptsLt.Count - 1];
            for (int i = 0; i < pCorrCptsLt.Count - 1; i++)
            {
                dblDiffAngle[i] = CGeoFunc.CalAngle(dblFrDiffX[i], dblFrDiffY[i], dblToDiffX[i], dblToDiffY[i]);
            }

            //计算最终的值
            double dblSumNumerator   = 0;
            double dblSumDenominator = 0;

            //double dblSumDenominator = dblFrAngle[0] * (dblFrDis[pCorrCptsLt.Count - 2] + dblFrDis[0]) + dblToAngle[0] * (dblToDis[pCorrCptsLt.Count - 2] + dblToDis[0]);
            for (int i = 0; i < pCorrCptsLt.Count - 1; i++)
            {
                dblSumNumerator += dblDiffAngle[i] * (dblFrDis[i] + dblToDis[i]);
                //dblSumDenominator += dblFrAngle[i] * (dblFrDis[i-1] + dblFrDis[i]) + dblToAngle[i] * (dblToDis[i-1] + dblToDis[i]);
                dblSumDenominator += dblFrDis[i] + dblToDis[i];
            }

            double dblSimilarity = 1 - dblSumNumerator / (Math.PI * dblSumDenominator);

            return(dblSimilarity);
        }
コード例 #2
0
        public void RightAngelSimplification(CPolyline cpl, ref List <CPolyline> Cpllt, double dblThreshold, double verysmall)
        {
            // step1 首先顾及直角,对于每一条polyline,遍历线的除首尾点以外的点,找出夹角为90°±5°的特殊顶点
            double        dblAngelThreshold = Convert.ToDouble(this.TxtAngelThreshold.Text);
            List <CPoint> CptLt             = new List <CPoint>();

            for (int i = 1; i < cpl.CptLt.Count - 1; i++)
            {
                List <CPoint> cptlt = new List <CPoint>();
                // Step2 求各个特殊顶点包括扩展边在内的临边,主要是求扩展边
                if (Math.Abs(CGeoFunc.CalAngle(cpl.CptLt[i - 1], cpl.CptLt[i], cpl.CptLt[i + 1]) - Math.PI / 2) <= dblAngelThreshold * Math.PI / 180)
                {
                    cptlt.Add((cpl.CptLt[i - 1]));
                    cptlt.Add((cpl.CptLt[i + 1]));

                    for (int j = i - 1; j > 0; j--)
                    {
                        if (CGeoFunc.CalAngle(cpl.CptLt[i - 1], cpl.CptLt[i], cpl.CptLt[j - 1], cpl.CptLt[j]) < dblAngelThreshold * Math.PI / 180)
                        {
                            cptlt.Remove(cpl.CptLt[j]);
                            cptlt.Add(cpl.CptLt[j - 1]);
                        }
                        else
                        {
                            break;
                        }
                    }
                    for (int j = i + 1; j < cpl.CptLt.Count - 1; j++)
                    {
                        if (CGeoFunc.CalAngle(cpl.CptLt[i], cpl.CptLt[i + 1], cpl.CptLt[j], cpl.CptLt[j + 1]) < dblAngelThreshold * Math.PI / 180)
                        {
                            cptlt.Remove(cpl.CptLt[j]);
                            cptlt.Add(cpl.CptLt[j + 1]);
                        }
                        else
                        {
                            break;
                        }
                    }
                }
                //Step3 找出各个满足条件(两条邻边足够长)的特殊顶点,然后将它们视为断点进行分割

                if (cptlt.Count == 2)
                {
                    if (CGeoFunc.CalDis(cpl.CptLt[i], cptlt[0]) >= dblThreshold && CGeoFunc.CalDis(cpl.CptLt[i], cptlt[1]) >= dblThreshold)
                    {
                        CptLt.AddRange(cptlt);
                        CptLt.Add(cpl.CptLt[i]);
                    }
                }
            }
            //删除CptLt中的重复点
            for (int i = 0; i < CptLt.Count; i++)
            {
                for (int j = CptLt.Count - 1; j >= i + 1; j--)
                {
                    if (CptLt[i].Equals2D(CptLt[j], verysmall))
                    {
                        CptLt.RemoveAt(j);
                    }
                }
            }
            //分割断点
            for (int i = CptLt.Count - 1; i >= 0; i--)
            {
                if (CptLt[i].Equals2D(cpl.CptLt[0], verysmall) || CptLt[i].Equals2D(cpl.CptLt[cpl.CptLt.Count - 1], verysmall))
                {
                    CptLt.RemoveAt(i);
                }
            }
            List <CPolyline> Cpllt1 = new List <CPolyline>();

            Cpllt1.Add(cpl);
            for (int i = 0; i < CptLt.Count; i++)
            {
                int intnum = 0;
                for (int j = 0; j < Cpllt1.Count; j++)
                {
                    for (int k = 1; k < Cpllt1[j].CptLt.Count - 1; k++)
                    {
                        if (CptLt[i].Equals2D(Cpllt1[j].CptLt[k], verysmall))
                        {
                            List <CPoint> cptlt1 = new List <CPoint>();
                            List <CPoint> cptlt2 = new List <CPoint>();
                            for (int n = 0; n <= k; n++)
                            {
                                cptlt1.Add(Cpllt1[j].CptLt[n]);
                            }
                            for (int n = k; n < Cpllt1[j].CptLt.Count; n++)
                            {
                                cptlt2.Add(Cpllt1[j].CptLt[n]);
                            }
                            Cpllt1.RemoveAt(j);
                            CPolyline cpl1 = new CPolyline(Cpllt1.Count + 1, cptlt1);
                            Cpllt1.Add(cpl1);
                            CPolyline cpl2 = new CPolyline(Cpllt1.Count + 2, cptlt2);
                            Cpllt1.Add(cpl2);
                            intnum += 1;
                            break;
                        }
                    }

                    if (intnum == 1)
                    {
                        break;
                    }
                }
            }
            for (int i = 0; i < Cpllt1.Count; i++)
            {
                List <CPoint> cptlt0 = new List <CPoint>();
                for (int j = 0; j < Cpllt1[i].CptLt.Count; j++)
                {
                    CPoint cpt = new CPoint(j, (IPoint)Cpllt1[i].CptLt[j]);
                    cptlt0.Add(cpt);
                }
                CPolyline cpl1 = new CPolyline(i, cptlt0);
                Cpllt.Add(cpl1);
            }
        }
コード例 #3
0
        private void btnRunCircle_Click(object sender, EventArgs e)
        {
            double        dblRadius        = Convert.ToDouble(this.txtRadius.Text);
            string        strSelectedLayer = this.cboLayer.Text;
            IFeatureLayer pFeatureLayer    = null;

            CParameterInitialize ParameterInitialize = _DataRecords.ParameterInitialize;

            //获取线状要素
            try
            {
                for (int i = 0; i < ParameterInitialize.m_mapFeature.LayerCount; i++)
                {
                    if (strSelectedLayer == ParameterInitialize.m_mapFeature.get_Layer(i).Name)
                    {
                        pFeatureLayer = (IFeatureLayer)ParameterInitialize.m_mapFeature.get_Layer(i);
                    }
                }
            }
            catch (Exception)
            {
                MessageBox.Show("Please select a feature layer");
                return;
            }
            //读取线数据
            List <CPolyline> CPolylineLt = CHelpFunc.GetCPlLtByFeatureLayer(pFeatureLayer);
            CPolyline        cpl         = CPolylineLt[0];

            //将线状要素分成3600份(得到3601个坐标点)
            List <CPoint> cptlt = new List <CPoint>();

            for (int i = 0; i <= 3600; i++)
            {
                IPoint outPoint = new PointClass();
                double dblRatio = Convert.ToDouble(i) / 3600;
                cpl.pPolyline.QueryPoint(esriSegmentExtension.esriNoExtension, dblRatio, true, outPoint);
                CPoint cpt = new CPoint(i, outPoint);
                cptlt.Add(cpt);
            }

            //将圆分成3600份(得到3601个坐标点)
            List <CPoint> CircleCptLt = new List <CPoint>();
            double        dblAdd      = Math.PI / 1800;
            double        dblHalfPI   = Math.PI / 2;

            for (int i = 0; i <= 3600; i++)
            {
                double dblAngle   = i * dblAdd;
                double dblCricleX = dblRadius * Math.Cos(dblAngle + dblHalfPI);  //由于本方法是从“最顶上的点”开始的,因此需加“PI / 2”
                double dblCricleY = dblRadius * Math.Sin(dblAngle + dblHalfPI);  //由于本方法是从“最顶上的点”开始的,因此需加“PI / 2”
                CPoint cpt        = new CPoint(i, dblCricleX, dblCricleY);
                CircleCptLt.Add(cpt);
            }

            //由于物体是均匀的,各长度一致,因此不需定义数组
            double dblFrDis = CGeoFunc.CalDis(CircleCptLt[0], CircleCptLt[1]);
            double dblToDis = CGeoFunc.CalDis(cptlt[0], cptlt[1]);

            //Fr线段和To线段之间的角度差(设定为必然小于180度,用余弦求)
            double[] dblDiffAngle = new double[3600];
            for (int i = 0; i < 3600; i++)
            {
                dblDiffAngle[i] = CGeoFunc.CalAngle(CircleCptLt[i], CircleCptLt[i + 1], cptlt[i], cptlt[i + 1]);
            }

            //计算最终的值
            double dblSumNumerator   = 0;
            double dblSumDenominator = 0;

            for (int i = 0; i < 3600; i++)
            {
                dblSumNumerator   += dblDiffAngle[i] * (dblFrDis + dblToDis);
                dblSumDenominator += dblFrDis + dblToDis;
            }

            double dblSimilarity = 1 - dblSumNumerator / (Math.PI * dblSumDenominator);

            MessageBox.Show(dblSimilarity.ToString());
        }