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

y-y0=k(x-x0)

(y-y0)^2 +
（x-x0)^2
=d^2

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>();
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];
}
//如果有内环，添加内环
if (interiorRingPoints != null)
{
foreach (IPoint[] pc in interiorRingPoints)
{
IPointCollection inRing = new RingClass();
foreach (IPoint inP in pc)