两相交的直线段夹角平分的直线上过交点距离为d的另一点求解公式

两相交的直线段夹角平分的直线上过交点距离为d的另一点求解公式
问题描述:
已知p0,p1,pN三个点,p0到p1走向直线段,pN到p0走向直线段,相交于p0点,
则pN到p0到p1夹角为a,平分夹角为a/2,求经过p0点方向角为平分线上距离p0点距离为d的点p(x,y)坐标值。
在这里插入图片描述
平分线点斜式方程为:
y-y0=k(x-x0)

两点距离公式为:
(y-y0)^2 +
(x-x0)^2
=d^2

斜率k=tg(a)

联合解方程组:
y-y0=k(x-x0)
(y-y0)^2 +
(x-x0)^2
=d^2

Mathematica 9 解公式表达式:

In[4]:= Solve[{d^2==(x-x0)^2+(y-y0)^2,(y-y0)==k*(x-x0)},{x,y}]

解结果:
在这里插入图片描述

文本公式:

In[4]:= Solve[{d^2==(x-x0)^2+(y-y0)^2,(y-y0)==k*(x-x0)},{x,y}]

                      2    2  2          2
               -Sqrt[d  + d  k ] + x0 + k  x0
Out[4]= {{x -> ------------------------------, 
                                2
                           1 + k
 
                     2       2                       3
             k Sqrt[d  (1 + k )]            k x0    k  x0
>     y -> -(-------------------) - k x0 + ------ + ------ + y0}, 
                        2                       2        2
                   1 + k                   1 + k    1 + k
 
                 2    2  2          2                  2       2                      3
           Sqrt[d  + d  k ] + x0 + k  x0       k Sqrt[d  (1 + k )]           k x0    k  x0
>    {x -> -----------------------------, y -> ------------------- - k x0 + ------ + ------ + y0}}
                           2                              2                      2        2
                      1 + k                          1 + k                  1 + k    1 + k

In[5]:= 

在这里插入图片描述

//创建界址点注记  宗地 如:J1,J2
        private void createZJ_JZD_JX(ZHFeaturePolyLine from_zhFeat, IFeatureClass toFc)
        {
            IGeometry geo = from_zhFeat.pFeature.ShapeCopy;
            if (geo != null && geo is IPolygon)
            {
                IPolygon pn = geo as IPolygon;
                IPoint[] pointArray = zjTool.getPoints(pn).ToArray();
                if (pointArray != null && pointArray.Length <= 2)
                {   //跳过 不能构面的线
                    return;
                }
                string jNR = "";
                IPoint p0 = null;
                IPoint p1 = null;
                IPoint pN = null;
                //长度注记
                for (int i = 0; i < pointArray.Length; i++)
                {
                    //
                    int lastIndex = i + 1;
                    if (lastIndex >= pointArray.Length-1)
                    {
                        break;
                    }
                    if(i==0)
                    {
                        p0 = pointArray[i];
                        p1 = pointArray[i + 1];
                        pN= pointArray[pointArray.Length-2];
                    }
                    else if(i== pointArray.Length-2)
                    {
                        p0 = pointArray[i];
                        p1 = pointArray[0];
                        pN = pointArray[i - 3];
                    }
                    else
                    {
                        p0 = pointArray[i];
                        p1 = pointArray[i + 1];
                        pN = pointArray[i-1];

                    }                    
                    double A_P0_1 = zjTool.getAngleOfLine(p0, p1);
                    double A_PN_0= zjTool.getAngleOfLine(pN, p0);
                    double A_delta = zjTool.getAngleLine2Line(p0, pN, p1);// Math.Atan(Math.Abs(Math.Tan(A_PN_0) - Math.Tan(A_P0_1))/1+ Math.Tan(A_PN_0)* Math.Tan(A_P0_1));
                    
                    double A_delta_2 = A_delta / 2.0;
                    //平分线方向角a               
                    double A_lineMid = A_PN_0 + A_delta_2;  //凸多边形
                    if(Math.Abs(A_PN_0- A_P0_1)<0.0001)
                    {
                        //三点共线 //凸多边形
                    }
                    else
                    {
                        double Area_delta = zjTool.getAreaLine2Line(p0, pN, p1);
                        if (Area_delta < 0)
                        {   //凹多边形
                            A_lineMid = A_PN_0 - A_delta_2;
                        }
                    }
                    
                    //修正角度                 
                    if (A_lineMid>=360)
                    {   
                        A_lineMid = A_lineMid - 360;   
                    }
                    if (A_lineMid<0)
                    {
                        A_lineMid = A_lineMid + 360;
                    }
                    //
                    jNR = "J" + (i + 1).ToString();

                    //double newAngleZJ = zjTool.newAngleZJ(AofLine);
                    //获取注记文字长度
                    ITextSymbol txtSymbol = zjTool.getTestTextSymbol(this.zjFontName, this.zjFontSize);
                    double zj_width = zjTool.getTextSize(txtSymbol, jNR, true);
                    //获取注记起始点
                    IPoint zjPoint = zjTool.getZJPoint_JZP(p0, A_lineMid, this.zjDistance, zj_width);
                    double A_P0_Pzj = zjTool.getAngleOfLine(p0, zjPoint);
                    if (Math.Abs(A_lineMid - A_P0_Pzj) < 0.0001)
                    {   //注记方向与线走向一致                        
                    }
                    else
                    {   //注记方向与线走向 相反
                        zjPoint = zjTool.getZJPoint_JZP_1(p0, A_lineMid, this.zjDistance, zj_width);
                    }
                    //
                    this.writeZJPoint(zjPoint, jNR, 0, from_zhFeat, toFc);
                    this.writeZJPoint(zjPoint, ".", 0, from_zhFeat, toFc);
                }
                //

            }
        }
        //-----
/// <summary>  
        /// 根据余弦定理求两个线段夹角  
        /// </summary>  
        /// <param name="o">端点</param>  
        /// <param name="s">start点</param>  
        /// <param name="e">end点</param>  
        /// <returns></returns>  
        public static double getAngleLine2Line(IPoint o, IPoint s, IPoint e)
        {
            double cosfi = 0, fi = 0, norm = 0;
            double dsx = s.X - o.X;
            double dsy = s.Y - o.Y;
            double dex = e.X - o.X;
            double dey = e.Y - o.Y;

            cosfi = dsx * dex + dsy * dey;
            norm = (dsx * dsx + dsy * dsy) * (dex * dex + dey * dey);
            cosfi /= Math.Sqrt(norm);

            if (cosfi >= 1.0) return 0;
            if (cosfi <= -1.0) return Math.PI;
            fi = Math.Acos(cosfi);

            if (180 * fi / Math.PI < 180)
            {
                return 180 * fi / Math.PI;
            }
            else
            {
                return 360 - 180 * fi / Math.PI;
            }
        }
        //计算三角形面积(负数表示逆时针,正数表示顺时针方向)
        public static double getAreaLine2Line(IPoint o,IPoint s,IPoint e)
        {
            List<IPoint> tList = new List<IPoint>();
            tList.Add(s);
            tList.Add(o);
            tList.Add(e);
            tList.Add(s);
            IPolygon pn = CreatePolygonNoSimplify(tList.ToArray(),null);
            return (pn as IArea).Area;
        }
        //
        public static IPoint getZJPoint_JZP(IPoint p0, double A_lineMid, double d, double zj_width)
        {            
            if (A_lineMid < 1e-13)
            {    //与X轴重叠
                IPoint pp = new PointClass();
                pp.X = p0.X + d;   //-d
                pp.Y = p0.Y;
                return pp;
            }
            double K = Math.Tan(A_lineMid*Math.PI/180.0);  //转为弧度角
            double KK = K * K;
            double KKK = KK * K;
            double KK_1 = 1 + KK;
            double sqrt_1_kk = Math.Sqrt(1 + KK);
            //p在直线上p0+A_lineMid
            double x = (-d * sqrt_1_kk + p0.X + KK * p0.X) / KK_1;
            double y = -1 * K * d * sqrt_1_kk / KK_1  - K * p0.X +(K * p0.X) / KK_1 + (KKK * p0.X) / KK_1+ p0.Y;
            //
            IPoint p = new PointClass();
            p.X = x;
            p.Y = y;
            return p;
            //          
        }
        public static IPoint getZJPoint_JZP_1(IPoint p0, double A_lineMid, double d, double zj_width)
        {
            if (A_lineMid < 1e-13)
            {    //与X轴重叠
                IPoint pp = new PointClass();
                pp.X = p0.X + d;   //-d
                pp.Y = p0.Y;
                return pp;
            }
            double K = Math.Tan(A_lineMid * Math.PI / 180.0);
            double KK = K * K;
            double KKK = KK * K;
            double KK_1 = 1 + KK;
            double sqrt_1_kk = Math.Sqrt(1 + KK);
            //p在直线上p0+A_lineMid
            double x = (d * sqrt_1_kk + p0.X + KK * p0.X) / KK_1;
            double y = K * d * sqrt_1_kk / KK_1 - K * p0.X + (K * p0.X) / KK_1 + (KKK * p0.X) / KK_1 + p0.Y;
            //
            IPoint p = new PointClass();
            p.X = x;
            p.Y = y;
            return p;
            //          
        }
public static IPolygon CreatePolygonNoSimplify(IPoint[] exteriorRingPoints, IPoint[][] interiorRingPoints)
        {
            IPolygon r = new PolygonClass();
            IGeometryCollection geos = r as IGeometryCollection;
            //添加外环
            IPointCollection exRing = new RingClass();
            for(int i=0;i< exteriorRingPoints.Length;i++)// (IPoint p in exteriorRingPoints)
            {
                IPoint p = exteriorRingPoints[i];
                exRing.AddPoint(p);
            }               
            geos.AddGeometry(exRing as IGeometry);
            //如果有内环,添加内环
            if (interiorRingPoints != null)
            {
                foreach (IPoint[] pc in interiorRingPoints)
                {
                    IPointCollection inRing = new RingClass();
                    foreach (IPoint inP in pc)
                        inRing.AddPoint(inP);
                    geos.AddGeometry(inRing as IGeometry);
                }
            }            
            return r;
        }
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页