二十年没有碰数学了,对下面这个问题突然不知道如何下手:给两个端点(X1, Y1)和(X2, Y2),然后划出一条线。
线的某一个端点(X1, Y1),要划一个三角型的箭头。
已知三角型的高度(从等边三角顶点到三角其它两端点的中间)为 H, 
而两端点到两端点的中间点长度为 L(就是两端点距离 2L),
(两端点的中间点当然要在线上啦)
要如何计算那两个端点的座标(X3, Y3)(X4, Y4)呢﹖

解决方案 »

  1.   

    有极坐标比较容易实现。---------------------->
    A                      B以点B作为极坐标的原点,分别向线段AB的两侧以同样的极半径r转动同样大小的角度θ
    r决定了箭头的长度
    θ决定的箭头的宽度
      

  2.   

    *(x3,y3)
                      /|
              (x1,y1)*-|-------------------*---------------------*(x2,y2)------
                      \|
                       *(x4,y4)
                     |H|                   
                     |<---------L--------->|不知道楼主是这个意思吗?
      

  3.   


                       *(x3,y3)
                      /|
              (x1,y1)*-|-------------------*---------------------*(x2,y2)------
                      \|
                       *(x4,y4)
                     |H|                   
                     |<---------L--------->|
      

  4.   

    *(x3,y3)
             /| L
     (x1,y1)*-|-------------------*---------------------*(x2,y2)
             \| L
              *(x4,y4)
            |H|                   
     
    嗯,果然用图比较好表达,
    不过,Point(x1, y1) 和 Point(x2, y2) 不会刚好在一条线上哦。
    那怎么计算 Point(x3, y3) 和 Point(x4, y4) 呢﹖
      

  5.   

    yuvotesyg518, 
    你的说法似乎有理,但若 (x1, y1), (x2, y2) 不在一条线上,那 θ 角的换算要怎么做呢﹖ 
    你可以说得再仔细一点吗﹖
      

  6.   

    ICMGDCHN, 画起来容易,但实际算起来,
    以我来说,不太容易。
    我再强调一次,
    (x1, y1), (x2, y2) 不一定在一条线上,
    究竟怎么算Point(x3, y3) 和 Point(x4, y4)呢﹖看起来像是初中数学,可是一下子要算,
    却不知从何算起,
    总觉得有一两个数据不知怎么算出来。
    请你们帮忙一下,谢谢!
      

  7.   

    晕,两点确定一条直线,(x1,y1),(x2,y2)怎么可能不在一条直线上呢?
    我的算法是说:以点B作为极坐标原点
    以AB或BA作为极坐标轴
      

  8.   

    用向量方法算起来也不难呀,反正是计算机去算将向量化为复数的表达方式,X=RcosA,Y=RsinA;再用上向量加减运算,挺简单的呀
      

  9.   

    丢脸,原来我又表达错误了。
    我要说的是(x1,y1),(x2,y2)未必x1=x2, 或 y1=y2, 
    也就是说 (x1, y1) 与 (x2, y2) 形成一条直线,
    未必平行或垂直于 x 轴。
    (竟然说成「不在一条直线」,
    昨天打字时一定是迷迷糊糊了,
    希望你们猜到我的意思)yuvotesyg518 和 ICMGDCHN 的说明,我有一点懂了,
    我不懂何谓极坐标,
    不过看你们的说明,
    很显然是要忘了原本的x, y 轴所形成的坐标。 如此,我的问题变成如下:
    怎么以 AB 或 BA 作为极坐标轴﹖
    这句话看来容易,我也懂了,
    但,怎么叫电脑懂呢﹖
    是不是要想办法将(x1, y1)(x2, y2)所形成的直线斜率,
    换成 θ 角呢﹖
    X=Rcosθ ,Y=Rsinθ 
    这算法很简单,
    似乎只要将(x1, y1)(x2, y2)所形成的直线斜率换成 θ 就可以应用了,
    是不是这样﹖请各位再多说一点,
    我正好学学怎么处理极坐标的问题,
    虽然这里不是「数学版」,呵!
    但各位请别介意。
      

  10.   


                *p3(x3,y3)
               /| L
     p1(x1,y1)*-|-------------------*---------------------*p2(x2,y2)
               \| L
                *p4(x4,y4)
              |H|   通过计算p1p3的长度得到(x3,y3)
    通过计算p1p4的长度得到(x4,y4)
      

  11.   


                *p3(x3,y3)
               /| L
     p1(x1,y1)*-|-------------------*---------------------*p2(x2,y2)
               \| L
                *p4(x4,y4)
              |H|   通过计算p1p3,p2p3的长度得到(x3,y3)
    通过计算p1p4,p2p4的长度得到(x4,y4)
      

  12.   

    哈哈,楼主说的差不多了
    所谓的
    X=Rcosθ ,Y=Rsinθ 
    不正是极坐标公式吗?极坐标ρ(r,θ)换算成直角坐标就是:
    X=ρcosθ
    Y=ρsinθ现在,我按上图的意思来说明:我把(x1,y1)当成极坐标的坐标原点,也就是说点(x1,y1)的极坐标为ρ(0,0)
    这样,点(x2,y2)的极坐标就好求了,设为ρ(L,α),其中,L是直线的长度,tanα是斜率这样,点(x3,y3)的极坐标就是ρ(r,α+θ),点(x4,y4)的极坐标就是ρ(r,α-θ)
    其中r是等腰三角形的斜边长。最后,利用上面的公式划成直角坐标就好了!
      

  13.   

    俺粘个代码..unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, DB, DBClient, MConnect, SConnect,unit2, StdCtrls ,Math ;type  TForm1 = class(TForm)
        SocketConnection1: TSocketConnection;
        Button1: TButton;
        procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        function GetP3(PB,PE:TPoint):TPoint;
        function GetP1(Point3,PB:TPoint):TPoint;
        function GetP2(Point3,PB:TPoint):TPoint;
      private
        { Private declarations }
        procedure DoDraw(Des:TCanvas);
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation
    var
      PBegin:TPoint;
      PEnd:TPoint;
      P1:TPoint;
      P2:TPoint;
      P3:TPoint;
    const
      TriangleHeight:integer=15; //三角形高度? 俺E文不好.写的变量名要是错了别砸俺
      BottomLenght:integer=4;   //底边长的一半?俺E文不好.写的变量名要是错了别砸俺
    {$R *.dfm}procedure TForm1.DoDraw(Des: TCanvas);
    //     |
    //   4 | 1
    //-------------
    //   3 | 2
    //     |
    begin
      //画线
      Des.MoveTo(PBegin.X,PBegin.Y);
      Des.LineTo(PEnd.X,PEnd.Y);
      //取点
      P3 := GetP3(PBegin,PEnd);
      P1 := GetP1(P3,PBegin);
      P2 := GetP2(P3,PBegin);
      //用红色圈出P3点
      Des.Pen.Color := clRed;
      Des.Ellipse(P3.X-2,P3.Y-2,P3.X+2,P3.Y+2);
      Des.Pen.Color := clBlack;
      //用蓝色圈出P1点
      Des.Pen.Color := clBlue;
      Des.Ellipse(P1.X-2,P1.Y-2,P1.X+2,P1.Y+2);
      Des.Pen.Color := clBlack;
      //用蓝色圈出P2点
      Des.Pen.Color := clBlue;
      Des.Ellipse(P2.X-2,P2.Y-2,P2.X+2,P2.Y+2);
      Des.Pen.Color := clBlack;
      //四个点找好了.分别是PEnd,P1,P2,P3把三角形描出来就好了
      Des.MoveTo(PEnd.X,PEnd.Y);
      Des.LineTo(P1.X,P1.Y);
      Des.LineTo(P3.X,P3.Y);
      Des.LineTo(P2.X,P2.Y);
      Des.LineTo(PEnd.X,PEnd.Y);
    end;procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      PBegin.X := X ;
      PBegin.Y := Y ;
    end;procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      PEnd.X := X ;
      PEnd.Y := Y ;
      DoDraw(Form1.Canvas);
    end;function TForm1.GetP1(Point3,PB:TPoint): TPoint;
    var
      A,B,C:Double;D,E:integer;
    begin
      A := Point3.X - PB.X ;
      B := Point3.Y - PB.Y ;
      C := sqrt(sqr(a)+sqr(b));  D := Round( b / c * BottomLenght);
      E := Round( a / c * BottomLenght);  result.X := Point3.X + D;
      Result.Y := Point3.Y - E;
    end;function TForm1.GetP2(Point3, PB: TPoint): TPoint;
    var
      A,B,C:Double;D,E:integer;
    begin
      A := Point3.X - PB.X ;
      B := Point3.Y - PB.Y ;
      C := sqrt(sqr(a)+sqr(b));  D := Round( b / c * BottomLenght);
      E := Round( a / c * BottomLenght);  result.X := Point3.X - D;
      Result.Y := Point3.Y + E;
    end;function TForm1.GetP3(PB, PE: TPoint): TPoint;
    var
      A,B,C:Double;D,E:integer;
    begin
      A := PB.X - PE.X;
      B := PB.Y -PE.Y;
      C := sqrt(sqr(a)+sqr(b));  D := Round( a / c * TriangleHeight);
      E := Round( b / c * TriangleHeight);  result.X := PE.X + D;
      result.Y := PE.Y + E;
    end;
    end.
      

  14.   

    解释一下上面的代码..
    没有用到三角函数..是根据直角三角形定理来算的.
    其中GetP1,GetP2函数可以写在一起的.另外
    极坐标系和笛卡座标系的转换类我原来做过
    什么时间有空在俺硬盘上翻翻再粘上来吧..那里用到很多Sqrt和Sqr还有三角函数..好象不大合理..
      

  15.   

    {
                *p1
               /| BottomLenght
         PEnd *-|-----------------------------------------*PBegin
               \| BottomLenght
                *P2
              | |
          TriangleHeight
    }
      

  16.   

    楼主还要做一些必要的除零检查和Point值的检查
      

  17.   

    首先要谢谢 10975037(猩猩),
    你提供的程式码,我已测试并应用了,
    写得很好,比我自己想出来的方法要好得多。
    因此我把原本写的程式码删除了,
    替换成你写的。我原本的写法,
    是使用 Sin=1/SQRT(1+SQR(Cot)) 这个公式,
    而 Tan 就是斜率,Cot 就是 1/Tan
    如此,即可计算出来,
    不过程式很长、很臭,
    虽然是想了两天才有的写法,
    但因为太长太臭,
    我才决定刪掉,
    改使用 10975037(猩猩) 的做法。至于 yuvotesyg518(小不点) , 
    我整个下午都在想你提供的做法,
    你的做法,
    大部份我都看得懂了,
    但是却写不出程式码来,
    不知道你愿意不愿意仿 10975037(猩猩) 的写法,
    把你的方法也写一个例子出来呢﹖当然,找到答案我已经很满足了,
    实在不好意思强迫你在百忙中帮忙写例子,
    但是,极坐标的做法,
    我的确很有兴趣,
    因此才花了一个下午来思考
    (并在网上找资料),
    可惜我以前高中没有学过极坐标,
    思考起来,事倍功半,
    因此才有这「不情之请」,
    你若帮忙,我很感谢你,
    如果你不愿意,
    我也没有话说,
    仍然会给你们分。
    先在这里谢谢你们了,
    今天学了不少。yuvotesyg518(小不点) ,
    等你的回应后,
    我便要结帖了。
      

  18.   

    To 10975037(猩猩) , 除零检查似乎没有必要,
    只要在所有 C := sqrt(sqr(a) + sqr(b)); 加上两行程式码,
    应该就不会有问题了。
    加的程式码如下所示,  C := sqrt(sqr(a) + sqr(b));
      if C=0 then
        C:=TriangleHeight;再次谢谢你了。
      

  19.   

    仅将 10975037(猩猩) 提供的程式码,
    修改后成为我用的程式码粘贴于此,
    以利后人,procedure TMyObject.Paint;
    var
      P: TPoint;  function GetP(PB, PE: TPoint): TPoint;
      var
        X, Y, L: Double;
        DX, DY: integer;
      begin
        X := PB.X - PE.X;
        Y := PB.Y - PE.Y;
        L := sqrt(sqr(X) + sqr(Y));    if L = 0 then
          L := FArrowHeight;    DX := Round(X / L * FArrowHeight);
        DY := Round(Y / L * FArrowHeight);    Result.X := PE.X + DX;
        Result.Y := PE.Y + DY;
      end;  function GetP2(P1, P2: TPoint; Direct: Integer): TPoint;
      var
        X, Y, L: Double;
        DX, DY: integer;
      begin
        X := P1.X - P2.X;
        Y := P1.Y - P2.Y;
        L := sqrt(sqr(X) + sqr(Y));
        if L = 0 then
          L := FArrowHeight;    DX := Round(Y / L * FArrowWidth) * Direct;
        DY := Round(X / L * FArrowWidth) * Direct;    Result.X := P1.X + DX;
        Result.Y := P1.Y - DY;
      end;begin
      if FInPaint then
        exit;  FInPaint := True;
      try
        inherited;
        with Canvas do
        begin
          Pen.Color := Self.Color;
          //畫線
          MoveTo(FFrom.X, FFrom.Y);
          LineTo(FTo.X, FTo.Y);      //         * F3Points[1]
          //        /| FArrowWidth
          //   FTo *-P-------------------------------* FFrom
          //        \| FArrowWidth
          //         * F3Point[2]
          //       |-| FArrowHeight      P := GetP(FFrom, FTo);
          F3Points[0] := FTo;
          F3Points[1] := GetP2(P, FFrom, 1);
          F3Points[2] := GetP2(P, FFrom, -1);      Brush.Color := Self.Color;
          Polygon(F3Points);
        end;
      finally
        FInPaint := False;
      end;
    end;
      

  20.   

    真气人,公司不准用delphi,我只能给你个javascript的答案,你自己翻译成delphi吧!
    function rotateVec(px,py,ang,isChLen,newLen){
      //矢量旋转函数,参数含义分别是x分量、y分量、旋转角、是否改变长度、新长度
      vx = px * Math.cos(ang)-py * Math.sin(ang);vy = px * Math.sin(ang) + py * Math.cos(ang);
      if(isChLen) {d=Math.sqrt(vx*vx+vy*vy);vx=vx/d*newLen;vy=vy/d*newLen; } 
      return new Array(vx,vy);
    }
    var x1=10; //(x1,y1)和(x2,y2)是两点
    var y1=10;
    var x2=50;
    var y2=50;
    var H=10; //箭头高度
    var L=7;//底边的一半
    var awrad=Math.atan(L/H);  //箭头角度
    var arraow_len=Math.sqrt(L*L+H*H);//箭头的长度
    var arrXY=rotateVec(x2-x1,y2-y1,awrad,true,arraow_len);
    var x3=x1+arrXY[0]; //(x3,y3)是第一端点
    var y3=y1+arrXY[1]
    var arrXY=rotateVec(x2-x1,y2-y1,-awrad,true,arraow_len);
    var x4=x1+arrXY[0];//(x3,y3)是第二端点
    var y4=y1+arrXY[1]
      

  21.   

    类似这样的问题不能使用高中数学的办法,因为存在好多的水平、斜率的垂直的判断,使用极坐标的效果也不好。
      最好使用矢量代数的办法,或者微分几何的办法,避开坐标系的限制。不仅这个简单图形,gis中更加复杂的图形计算也是如此。晚上我给你提供一个完整的计算箭头的delphi函数
      

  22.   

    有了,还有不少问题,试一下(小心喷饭!!)
    unit U_Line;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      TFrm_Line = class(TForm)
        procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure FormCreate(Sender: TObject);
        procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
          Y: Integer);
      private
        { Private declarations }
        stPoint, enPoint: TPoint;
        isLineMode: Boolean;
      public
        { Public declarations }
      end;var
      Frm_Line: TFrm_Line;implementation{$R *.dfm}procedure TFrm_Line.FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      stPoint.X:= X;
      stPoint.Y:= Y;
      enPoint:= stPoint;  isLineMode:= true;
    end;procedure TFrm_Line.FormMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    var
      k, angle: Real;
      X1, Y1, X2, Y2: Integer;
    begin
      if enPoint.X <> stPoint.X then
        k:= (enPoint.Y - stPoint.Y) / (enPoint.X - stPoint.X)
      else
        k:= 0;
      angle:= arctan(k);
      X1:= round(enPoint.X + 10 * cos(angle + PI / 180 * 15));
      Y1:= round(enPoint.Y + 10 * sin(angle + PI / 180 * 15));
      X2:= round(enPoint.X + 10 * cos(angle - PI / 180 * 15));
      Y2:= round(enPoint.Y + 10 * sin(angle - PI / 180 * 15));
      Canvas.LineTo(X1, Y1);
      Canvas.MoveTo(enPoint.X, enPoint.Y);
      Canvas.LineTo(X2, Y2);
      isLineMode:= false;
    end;procedure TFrm_Line.FormCreate(Sender: TObject);
    begin
      isLineMode:= false;
    end;procedure TFrm_Line.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    begin
      if not isLineMode then Exit;  Canvas.Pen.Mode:= pmMergePenNot;
      Canvas.MoveTo(stPoint.X, stPoint.Y);
      Canvas.LineTo(enPoint.X, enPoint.Y);  Canvas.MoveTo(stPoint.X, stPoint.Y);
      Canvas.LineTo(X, Y);  enPoint.X:= X;
      enPoint.Y:= Y;
    end;end.
      

  23.   

    To yuvotesyg518(小不点) , 谢谢你的支持,
    使今天的讨论更加美好。
    刚刚才看完帖,
    尚未测试,等一下再回帖告知测试的心得。To cxz7531(大花猫)今天又来了一个新的回复者,
    并且提供了「矢量旋转」的新方法来,
    真是开心,
    虽然看不懂「矢量旋转」,
    但多了一个答案,
    我还是高兴得不得了。
    看来我下午又得花一点时间思考思考了。
    不知道高中程度的我,
    有没有办法想通「矢量旋转」。说真的,一个「极座标」已经有一点点超过我的能力了。
    不过,我会加油就是了。顺便提一下,我和我老婆也很喜欢「花猫」哦!-----------------------------------没有想到,
    一个简单的问题,
    引导出这么多的讨论与办法来,
    是我始料未及的。
    并且让我学习了「极座标」入门,
    真是有意思的讨论。说起来真是「书到用时方恨少」,
    后悔数学只学习到高中程度,
    大学后便没有学过数学,
    要不然一定收获更大。嗯,由于「大花猫」答允晚上要提供函数例子,
    我应该再等等「大花猫」再结帖,
    很抱歉不能如yuvotesyg518(小不点)的预期早点结帖了。
      

  24.   

    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs;type
      TForm1 = class(TForm)
        procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
      private
        { Private declarations }
        FB, FE: TPoint;
        function rotateVec(p: Tpoint; ang, newline: Double): Tpoint;
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      FB.X := X;
      FB.Y := Y;
    end;procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    var
      L,H,Len,ang: double;
      x3, y3, x4, y4: Integer;
      pp, tpp: Tpoint;
    begin
      H:=15;    //高度
      L:=5;     //半底边
      Len:=sqrt(H*H+L*L);//箭头线长度
      ang:=arctan(L/H); //箭头的半顶角
      //-----------------
      // 画直线12
      FE.X := X;
      FE.Y := Y;
      form1.Canvas.MoveTo(FB.X, FB.Y);
      form1.Canvas.LineTo(FE.X, FE.Y);
      tpp.X := FE.X - FB.X;
      tpp.Y := FE.Y - FB.Y;
      //-----------------
      // 旋转ang角得到一条箭头线
      pp := rotateVec(tpp, ang,Len);
      x3 := pp.X + FB.X;
      y3 := pp.Y + FB.Y;
      form1.Canvas.MoveTo(FB.X, FB.Y);
      form1.Canvas.LineTo(x3, y3);
      //-----------------
      // 旋转-ang角得到另一条箭头线
      pp := rotateVec(tpp, -ang, Len);
      x4 := pp.X + FB.X;
      y4 := pp.Y + FB.Y;
      form1.Canvas.MoveTo(FB.X, FB.Y);
      form1.Canvas.LineTo(x4, y4);
    end;function TForm1.rotateVec(p: Tpoint; ang, newline: Double): Tpoint;
    {把矢量p旋转ang角得到新的矢量,并用新的长度newline}
    var
      vx, vy, d: Double;
    begin
      vx := p.x * cos(ang) - p.y * sin(ang);
      vy := p.x * sin(ang) + p.y * cos(ang);
      d := sqrt(vx * vx + vy * vy);
      result.X := round(vx / d * newline);
      result.Y := round(vy / d * newline);
    end;end.回 yuvotesyg518(小不点):你的办法基本上也是普适的,但需要求斜率,不能适用于直线垂直或者接近垂直的情况
      

  25.   

    楼主,我搞定了!!
    绝对没问题,还有橡皮筋效果呢!!
    --------------------------------------------
    unit U_Line;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      TFrm_Line = class(TForm)
        procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure FormCreate(Sender: TObject);
        procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
          Y: Integer);
      private
        { Private declarations }
        stPoint, enPoint: TPoint;
        isLineMode: Boolean;
      public
        { Public declarations }
      end;var
      Frm_Line: TFrm_Line;implementation{$R *.dfm}procedure TFrm_Line.FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      stPoint.X:= X;
      stPoint.Y:= Y;
      enPoint:= stPoint;  isLineMode:= true;
    end;procedure TFrm_Line.FormMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    var
      k, angle: Real;
      X1, Y1, X2, Y2: Integer;
    begin
      isLineMode:= false;
      if (enPoint.X = stPoint.X) and (enPoint.Y = stPoint.Y) then Exit;  angle:= PI / 2;
      if enPoint.X <> stPoint.X then
      begin
        k:= (enPoint.Y - stPoint.Y) / (enPoint.X - stPoint.X);
        angle:= arctan(k);
      end;
      if k < 0 then angle:= PI + angle;
      if enPoint.Y > stPoint.Y then
        angle:= PI + angle
      else if enPoint.Y = stPoint.Y then
        if enPoint.X > stPoint.X then
          angle:= PI + angle;  X1:= round(enPoint.X + 10 * cos(angle + PI / 180 * 15));
      Y1:= round(enPoint.Y + 10 * sin(angle + PI / 180 * 15));
      X2:= round(enPoint.X + 10 * cos(angle - PI / 180 * 15));
      Y2:= round(enPoint.Y + 10 * sin(angle - PI / 180 * 15));  Canvas.MoveTo(enPoint.X, enPoint.Y);
      Canvas.LineTo(X1, Y1);
      Canvas.MoveTo(enPoint.X, enPoint.Y);
      Canvas.LineTo(X2, Y2);
    end;procedure TFrm_Line.FormCreate(Sender: TObject);
    begin
      isLineMode:= false;
    end;procedure TFrm_Line.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    begin
      if not isLineMode then Exit;  Canvas.Pen.Mode:= pmMergePenNot;
      Canvas.MoveTo(stPoint.X, stPoint.Y);
      Canvas.LineTo(enPoint.X, enPoint.Y);  Canvas.MoveTo(stPoint.X, stPoint.Y);
      Canvas.LineTo(X, Y);  enPoint.X:= X;
      enPoint.Y:= Y;
    end;end.
      

  26.   

    TO yuvotesyg518(小不点)
      X1:= round(enPoint.X + 10{三角斜边长} * cos(angle + PI / 180 * 15{三角顶角1/2}));
      Y1:= round(enPoint.Y + 10{三角斜边长} * sin(angle + PI / 180 * 15{三角顶角1/2}));
      X2:= round(enPoint.X + 10{三角斜边长} * cos(angle - PI / 180 * 15{三角顶角1/2}));
      Y2:= round(enPoint.Y + 10{三角斜边长} * sin(angle - PI / 180 * 15{三角顶角1/2}));好象离题了哈.嘿嘿.勿怪
      

  27.   

    谢谢你们大家,
    一个简单的问题,
    导出了你们的协助与提供各种可行方案,
    收获很多。To yuvotesyg518(小不点),
    看完你提供的源码后,
    我确定我昨天是懂你的说明了,
    唯一让我无法实作出来的,
    是从斜率算出角度,
    我不知道是使用 ArcTan()。
     
    感谢你的范例,
    让我学会了使用极坐标解法解我的问题。但我觉得 cxz7531(大花猫) 说得对,
    这方法因为需要求斜率,不能适用于直线垂直或者接近垂直的情况,
    使得程式码中必须多许多判断,
    以补斜率的不足,
    你赞同吗﹖
    (不知道这可不可以算是「教学相长」﹖)To cxz7531(大花猫),
    你的例子,
    受限于我的能力,
    一时间看不懂,
    你得给我一些时间消化,
    恕不在此回应了。不过,
    你的那段
    「其实几何图形本身具有内在性质,是跟坐标系无关的……
    用矢量法解决几何问题,完全避开坐标系,能做到坐标系无关」
    我很同意。------------------------------------------------------------有一点必须说明,
    我知道cxz7531(大花猫)的答案很好,
    我给cxz7531(大花猫)的反馈比别人少,
    是因为
    1.我的能力不足,需要时间理解(尤其是找资料);
    2.cxz7531(大花猫)的回复比其他人晚一些,
    而我认为该在这里结帖了,
    因为问题本身不难,
    从各位提供的解决方案中,
    只因为我有需求,可以获得学习的快感,
    不表示其他上网来看的人也有同感,
    因此,为避免再浪费大家的时间,
    我应该结帖了。过几天,我可能还有另外一个也是几何图形的问题要问,
    这几天且让我自己先做一做功课,自己想一想,
    实在不行,
    希望到时各位可以再给我支持。我的问题,
    靠大家帮忙,
    在此一并致谢。