代码之家  ›  专栏  ›  技术社区  ›  bernhof

将一行缩短若干像素

  •  12
  • bernhof  · 技术社区  · 16 年前

    我正在使用.NETGDI+绘制业务对象的自定义图表。除其他外,该图由连接对象的几条线组成。

    想象一个有半径的圆 =10个像素,以及具有起点(x1,y1)和终点(x2,y2)的线。如下图所示,圆位于直线端点的中心。

    Illustration

    如何计算标有红色圆圈的点,即圆圈与直线的交点?这将给我线的新端点,将其缩短10像素。


    解决方案

    具体地说,我试图组合一个函数,可以用圆角画一条线,可以找到 here .

    public void LengthenLine(PointF startPoint, ref PointF endPoint, float pixelCount)
    {
      if (startPoint.Equals(endPoint))
        return; // not a line
    
      double dx = endPoint.X - startPoint.X;
      double dy = endPoint.Y - startPoint.Y;
      if (dx == 0)
      {
        // vertical line:
        if (endPoint.Y < startPoint.Y)
          endPoint.Y -= pixelCount;
        else
          endPoint.Y += pixelCount;
      }
      else if (dy == 0)
      {
        // horizontal line:
        if (endPoint.X < startPoint.X)
          endPoint.X -= pixelCount;
        else
          endPoint.X += pixelCount;
      }
      else
      {
        // non-horizontal, non-vertical line:
        double length = Math.Sqrt(dx * dx + dy * dy);
        double scale = (length + pixelCount) / length;
        dx *= scale;
        dy *= scale;
        endPoint.X = startPoint.X + Convert.ToSingle(dx);
        endPoint.Y = startPoint.Y + Convert.ToSingle(dy);
      }
    }
    
    3 回复  |  直到 7 年前
        1
  •  14
  •   Cecil Has a Name    16 年前

    求方向向量,即让位置向量为(使用浮点数)B=(x2,y2)和A=(x1,y1),然后AB=B-A。通过除以向量的长度(Math.Sqrt(x x+y y) )。然后将方向向量AB乘以原始长度减去圆的半径,再加回到直线的起始位置:

    double dx = x2 - x1;
    double dy = y2 - y1;
    double length = Math.Sqrt(dx * dx + dy * dy);
    if (length > 0)
    {
        dx /= length;
        dy /= length;
    }
    dx *= length - radius;
    dy *= length - radius;
    int x3 = (int)(x1 + dx);
    int y3 = (int)(y1 + dy);
    

    编辑:修正了代码,aa,修正了最初的解释(以为你想让线从圆的中心延伸到周长:P)

        2
  •  5
  •   paxdiablo    16 年前

    我不知道你为什么要介绍这个圈子。对于一条从 (x2,y2) (x1,y1)

    (x2+p*(x1-x2),y2+p*(y1-y2))
    

    哪里 p 是您希望达到的水平的百分比。

    p = r/L
    

    所以在你的情况下, (x3,y3) 可计算为:

    (x2+(10/L)*(x1-x2),y2+(10/L)*(y1-y2))
    

    (x2=1,y2=5) (x1=-6,y1=22) ,它们的长度为sqrt(7 2. 2.

      (x2 + (10/l)      * (x1-x2) , y2 + (10/l)      * (y1-y2))
    = (1  + 0.543928293 * (-6- 1) , 5  + 0.543928293 * (22- 5))
    = (1  + 0.543928293 * -7      , 5  + 0.543928293 * 17     )
    = (x3=-2.807498053,y3=14.24678098)
    

    距离 (x3,y3) is sqrt(3.192501947) 2. + 7.753219015 )或者8.384776311,10到1亿分之一的差值,这只是因为我的计算器有舍入误差。

        3
  •  5
  •   Glorfindel Doug L.    7 年前

    可以使用类似的三角形。对于主三角形, d r R .

    r/d = (x2-a0)/(x2-x1) = (y2-b0)/(y2-y1)
    
    a0 = x2 + (x2-x1)r/d
    
    b0 = y2 + (y2-y1)r/d
    
    推荐文章