计算直线感应区

计算一条直线在指定的平行距离和端点距离的感应矩形区

        /// <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 };
        }



效果图


转载请注明出处。

原文地址:https://www.cnblogs.com/sparkleDai/p/7604900.html