如题

解决方案 »

  1.   

    是一点一点算出来的。比如说给出5个点  然后用下边的函数生成出来的。
    //离合函数
    procedure TForm1.smoothline(rl: rline; no:integer);
      procedure pMoveTo(x, y: single);
      var sx, sy: integer;
      begin
        sx:=round(x);sy:=round(y);
        Image1.Canvas.MoveTo(sx, sy);
      end;  procedure pLineTo(x, y: single);
      var sx, sy: integer;
      begin
        sx:=round(x);sy:=round(y);
          Image1.Canvas.LineTo(sx, sy);
      end;  procedure pPolyline(rl: rline; no:integer);
      var ii: integer;
      begin
         pMoveto(rl[0].x, rl[0].y);
         for ii := 1 to no-1 do pLineto(rl[ii].x, rl[ii].y);
      end;const step = 0.1;
          dist = 0.05;
    var
       k,m,l,j,cir1,ctl:integer;
       bb:char;
       a,b,x1,y1:array[1..5] of single;
       sn,sn1,sn2,cn,cn1,cn2,w2,w3,z,z1,a0,b0,sn4,cn4,
       p0,p1,p2,p3,q0,q1,q2,q3,xt,yt,xt1,yt1,lastx,lasty,p11,p21,q11,q21:single;   r,r1:single;
       x,y : ^xys;
    begin
         ctl:=1;sn2:=0;cn2:=0;sn1:=0;cn1:=0;     if (no<3) then begin
              pMoveTo(rl[0].x,rl[0].y);
              pLineTo(rl[1].x,rl[1].y);
          end;
          new(x);new(y);
          pMoveto(rl[0].x,rl[0].y);
          for k:=0 to no-1 do begin
             x^[k+2]:=rl[k].x;
             y^[k+2]:=rl[k].y;
          end;
          if ((abs(rl[0].x-rl[no-1].x)<0.05) and (abs(rl[0].y-rl[no-1].y)<0.05)) then begin
     x^[1]:=rl[no-1].x;
     y^[1]:=rl[no-1].y;
     x^[0]:=rl[no-2].x;
     y^[0]:=rl[no-2].y;
     x^[no+3]:=rl[1].x;
     y^[no+3]:=rl[1].y;
     x^[no+2]:=rl[0].x;
     y^[no+2]:=rl[0].y;
           end
          else begin
          p0:=x^[2]; p1:=x^[3]; p2:=x^[4];
          q0:=y^[2]; q1:=y^[3]; q2:=y^[4];
          x^[1]:=3*(p0-p1)+p2;
          y^[1]:=3*(q0-q1)+q2;
          p0:=x^[1]; p1:=x^[2]; p2:=x^[3];
          q0:=y^[1]; q1:=y^[2]; q2:=y^[3];
          x^[0]:=3*(p0-p1)+p2;
          y^[0]:=3*(q0-q1)+q2;
          p0:=x^[no+1]; p1:=x^[no-1]; p2:=x^[no];
          q0:=y^[no+1]; q1:=y^[no-1]; q2:=y^[no];
          x^[no+2]:=3*(p0-p2)+p1;
          y^[no+2]:=3*(q0-q2)+q1;
          p0:=x^[no+2]; p1:=x^[no+1]; p2:=x^[no];
          q0:=y^[no+2]; q1:=y^[no+1]; q2:=y^[no];
          x^[no+3]:=3*(p0-p1)+p2;
          y^[no+3]:=3*(q0-q1)+q2;
          end;      for m:=3 to no+1 do begin
     j:=m-2;
     for k:=1 to 5 do begin
                x1[k]:=x^[j];
                y1[k]:=y^[j];
                j:=j+1;
             end;
     for k:=1 to 4 do begin
                a[k]:=x1[k+1]-x1[k];
        b[k]:=y1[k+1]-y1[k];
     end;
     if m>=5 then begin sn1:=sn2;  cn1:=cn2; end;
     if ((a[2]=b[2]) and (a[2]=0)) then begin
        a[2]:=a[1];   b[2]:=b[1];
     end;
     if ((a[3]=b[3]) and (a[3]=0)) then begin
        a[3]:=a[2];   b[3]:=b[2];
     end
     else begin
        if ((a[4]=b[4]) and (a[4]=0)) then begin
             a[4]:=a[2];   b[4]:=b[2];
        end;
             end;         w2:=abs(a[3]*b[4]-a[4]*b[3]);
             w3:=abs(a[1]*b[2]-a[2]*b[1]);
          if ((w3=w2) and (w3=0)) then begin w2:=1; w3:=1; end;
             a0:=w2*a[2]+w3*a[3];   b0:=w2*b[2]+w3*b[3];
             r1:=a0*a0+b0*b0;
             r:=sqrt(r1)+0.0001;
     sn:=b0/r;    cn:=a0/r;
     if (m=3) then begin
        sn1:=sn;  cn1:=cn;
      end
             else begin
        sn2:=sn;   cn2:=cn;
                r1:=a[2]*a[2]+b[2]*b[2];
        r:=sqrt(r1);
                p0:=x1[2]; q0:=y1[2];
        p1:=r*cn1; q1:=r*sn1;
        p2:=3*a[2]-r*(cn2+2*cn1);
        q2:=3*b[2]-r*(sn2+2*sn1);
                p3:=(-2)*(x1[3]-x1[2])+r*(cn2+cn1);
                q3:=(-2)*(y1[3]-y1[2])+r*(sn2+sn1);
                z:=1;
        repeat
           z:=z*0.9;
           xt:=p0+z*(p1+z*(p2+z*p3))-x1[2];
           yt:=q0+z*(q1+z*(q2+z*q3))-y1[2];
                   r:=xt*xt+yt*yt;
                   r1:=sqrt(r);
                until (r1<=step);
        z1:=z;
        while(z<=1) do begin
           xt:=p0+z*(p1+z*(p2+z*p3));
           yt:=q0+z*(q1+z*(q2+z*q3));
                   plineto(xt,yt);
                   z:=z+z1;
                end;
             end;
        end;
        dispose(x);dispose(y);
    end;
      

  2.   

    随意给5个点的时候如果用moveto 和 lineto中间连成的是直线,我用上边的函数可以线变成平滑的曲线,但是这个函数我也看不大明白,不知道取最高点该如何实现,请指教。
      

  3.   

    实质上是画的折线, 只需要在pLineTo中记录下最高点的X和Y就行了。
    procedure TForm1.smoothline(rl: rline; no:integer); 
    var    //把var部分搬到前面来
      k,m,l,j,cir1,ctl:integer; 
      bb:char; 
      a,b,x1,y1:array[1..5] of single; 
      sn,sn1,sn2,cn,cn1,cn2,w2,w3,z,z1,a0,b0,sn4,cn4, 
      p0,p1,p2,p3,q0,q1,q2,q3,xt,yt,xt1,yt1,lastx,lasty,p11,p21,q11,q21:single; 
      r,r1:single; 
      x,y : ^xys; 
      XMax, YMax: Single;    //新增加两个变量,用于记录下最高点坐标值  procedure pMoveTo(x, y: single); 
      var sx, sy: integer; 
      begin 
        sx:=round(x);sy:=round(y); 
        Image1.Canvas.MoveTo(sx, sy); 
      end;   procedure pLineTo(x, y: single); 
      var sx, sy: integer; 
      begin 
        if y > YMax then
        begin 
          XMax := x;
          YMax := y;
        end;
        sx:=round(x);sy:=round(y); 
        Image1.Canvas.LineTo(sx, sy); 
      end;   ......begin
      XMax := -9999999;
      YMax := -9999999;
      ......
      dispose(x);dispose(y); 
      //此时的XMax, YMax为你所需的最高点坐标值
    end;