zoukankan      html  css  js  c++  java
  • 计算直线感应区

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

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



    效果图


    转载请注明出处。

  • 相关阅读:
    QuartzQuartz定时任务
    jdbc模糊查询、分页查询、联合查询
    PreparedStatement
    web服务器简述
    JDBC基本操作
    RMI
    Http编程
    2020毕业季业务开发宝典
    程序设计流程图
    系统概要框图
  • 原文地址:https://www.cnblogs.com/sparkleDai/p/7604900.html
Copyright © 2011-2022 走看看