计算一条直线在指定的平行距离和端点距离的感应矩形区
/// <summary> /// 计算P1P2直线的感应矩形区 /// </summary> /// <param name="p1"></param> /// <param name="p2"></param> /// <param name="parallelOffset">平行间距</param> /// <param name="endPointOffset">端点间距</param> /// <returns></returns> public PointF[] CalculateInductionRect(PointF p1, PointF p2, double parallelOffset, double endPointOffset) { var p1New = p1; var p2New = p2; var p_a = new PointF(); var p_b = new PointF(); var p_c = new PointF(); var p_d = new PointF(); if (p2.X == p1.X) {//平行Y轴 #region 平行Y轴 var minY = Math.Min(p1.Y, p2.Y); var maxY = Math.Max(p1.Y, p2.Y); //计算端点偏移距离后的P1点 var y1New_1 = p1.Y + endPointOffset; var y1New_2 = p1.Y - endPointOffset; //由于新点必须在P1P2直线的两端延长线上,所以Y不可能在P1P2点的Y之间 var y1New = (y1New_1 > minY && y1New_1 < maxY) ? y1New_2 : y1New_1; //计算端点偏移距离后的P1点 var y2New_1 = p2.Y + endPointOffset; var y2New_2 = p2.Y - endPointOffset; //由于新点必须在P1P2直线的两端延长线上,所以Y不可能在P1P2点的Y之间 var y2New = (y2New_1 > minY && y2New_1 < maxY) ? y2New_2 : y2New_1; p1New = new PointF(p1.X, (float)y1New); p2New = new PointF(p2.X, (float)y2New); //P1P2平行Y轴,平行偏移就即X的偏移 p_a.X = (float)(p1New.X - parallelOffset); p_a.Y = p1New.Y; p_b.X = (float)(p1New.X + parallelOffset); p_b.Y = p1New.Y; p_c.X = (float)(p2New.X + parallelOffset); p_c.Y = p2New.Y; p_d.X = (float)(p2New.X - parallelOffset); p_d.Y = p2New.Y; #endregion } else {//不平行Y轴 //斜率 double k = (p2.Y - p1.Y) / (p2.X - p1.X); //k平方 double kSquare = k * k; #region 计算端点距离延伸的新点 if (endPointOffset != 0) { var minX = Math.Min(p1.X, p2.X); var maxX = Math.Max(p1.X, p2.X); //依据距离公式和新点到P2点的斜率相等形成两个方程式,推导得出 var factorXForEndPoint = endPointOffset / Math.Sqrt(kSquare + 1); //计算端点偏移距离后的P1点 var x1New_1 = p1.X + factorXForEndPoint; var x1New_2 = p1.X - factorXForEndPoint; //由于新点必须在P1P2直线的两端延长线上,所以X不可能在P1P2点的X之间 var x1New = (x1New_1 > minX && x1New_1 < maxX) ? x1New_2 : x1New_1; //计算端点偏移距离后的P2点 var x2New_1 = p2.X + factorXForEndPoint; var x2New_2 = p2.X - factorXForEndPoint; //由于新点必须在P1P2直线的两端延长线上,所以X不可能在P1P2点的X之间 var x2New = (x2New_1 > minX && x2New_1 < maxX) ? x2New_2 : x2New_1; //y=kx+b //计算P1P2直线方程的截距 var b = p1.Y - k * p1.X; //基于截距式直线方程计算新的P1和P2点 var y1New = k * x1New + b; var y2New = k * x2New + b; p1New = new PointF((float)x1New, (float)y1New); p2New = new PointF((float)x2New, (float)y2New); } #endregion #region 计算与P1P2两边平行的四个点 //依据距离公式和新点到P2点的斜率相等形成两个方程式,推导得出 double factorX = parallelOffset * k / Math.Sqrt(kSquare + 1); p_a.X = (float)(p1New.X - factorX); p_b.X = (float)(p1New.X + factorX); p_c.X = (float)(p2New.X + factorX); p_d.X = (float)(p2New.X - factorX); //依据距离公式和新点到P2点的斜率相等形成两个方程式,推导得出 double factorY = parallelOffset / Math.Sqrt(kSquare + 1); p_a.Y = (float)(p1New.Y + factorY); p_b.Y = (float)(p1New.Y - factorY); p_c.Y = (float)(p2New.Y - factorY); p_d.Y = (float)(p2New.Y + factorY); #endregion } return new PointF[] { p_a, p_b, p_c, p_d }; }
效果图
转载请注明出处。