Canvasに描画する線の幅を太くした時、実線にならない方法は?

解決


のり  2004-01-05 20:05:05  No: 6516

いつもお世話になっております。

今回の質問なんですが、PaintBoxに描画する線の幅をあげると

psDash          破線
psDot          点線
psDashDot          一点鎖線
psDashDotDot     二点鎖線

が、実線になってしまいます。どうにかしてスタイルを維持できないでしょうか?
方法がありましたらご教授願います。


にしの  2004-01-05 20:54:29  No: 6517

できないと思います。
自前でコーディングするしかないかと。

単に、私が知らないだけかもしれませんが。


のり  2004-01-05 22:35:14  No: 6518

そうですか、わかりました!!
ありがとうございます。


sadoyama  URL  2004-01-06 09:21:29  No: 6519

PaintBoxは使ったことがないので、通用するかは解りませんが
TImage, TCanvas上での描画経験があります。

中村拓男さんのホームページ「中村の里」にある
TPathクラスを使うとあっけなく簡単に実現できます。
私は、同氏の著書「Delphi Graphic Secrets」で知りました。
記憶では、描画速度がやや落ちたように思います。


sadoyama  URL  2004-01-07 04:11:27  No: 6520

昨日は急いでいたのできちんと調べられませんでした。
補足をさせていただきます。

中村の里の該当ページ
    http://www.asahi-net.or.jp/~HA3T-NKMR/DGS/DownLoad.htm
このぺーじより  DHGL 1.2 (dhgl1.2.lzh, 3.63MB)  2002/9/26 版
をダウンロード

TPathはCommonフォルダのPathUtils.pasをusesして使います。
TPathの使い方は、
Chapter6\6-2\WideDashedLin\のデモプロジェクトにあります。


のり  2004-01-07 18:40:05  No: 6521

ありがとうございます!!

やってみますね!!


のり  2004-01-07 19:11:14  No: 6522

sadoyamaさん、ありがとうございます。

今、サンプルのソースを見ているのですが私のレベルでは、何がどうなっているのか分かりませんので、もしよろしければご教授願いたいのですが・・・

> PaintBoxは使ったことがないので、通用するかは解りませんが
> TImage, TCanvas上での描画経験があります。

  私がやっているのは、TPaintBoxのTCanvas上での描画です^^;
  説明不足ですいませんでした。

  現在、PolyLineを使ってPointで座標を指定し点と点と結ぶグラフを描画しているのですが^^;ソースは下記の様なものです。
  

//******************************************************************************
//  CanvasPaint            : グラフ描画
//   罫線を描画する
//   引数   : ACanvas   : ペイントボックス.キャンバス
//            ARect     : ペイントボックス領域
//   戻り値 : なし
//
//******************************************************************************
procedure TFm31RmsMain.CanvasPaint(ARect: TRect;p_PrintDataAry: PRMSItem;
                                   p_Property: TGraphPaint);
var
  iLoopCnt:    Integer;
  iZoom:       Integer;

  // グラフ描画関連
  pDataAry      : array[0..15] of TPoint;     // 座標変換配列
  pStart        : TPoint;                      // 基準開始座標
  pEnd          : TPoint;                      // 基準終了座標
  eGraphDmax    : Extended;                    // 環境設定画面 グラフDMAX
  eMeasureX      : Extended;                    // 1マスの幅
  eMeasureY      : Extended;                    // 1マスの高さ
begin

   // 画像を表示するCanvasを設定
  Case Pctl01.ActivePageIndex of
    0 : ActiveCanvas := Ptbo01RmsVsDen;
    1 : ActiveCanvas := Ptbo02RmsVsLog;
    2 : ActiveCanvas := Ptbo03Wiener;
    3 : ActiveCanvas := Ptbo04CTF01;
    4 : ActiveCanvas := Ptbo05CTF02;
  end;

  // ---------------------------------------------------------------------------
  // 初期設定
  // ---------------------------------------------------------------------------
  // グラフ縦軸の最大値
//  eGraphDmax    := m_objSensitManager.m_objIniFile.m_eRangeDMax;
  eGraphDmax := StrToFloat(EdtMax.Text);
  // 横軸の間隔を設定
  eMeasureX := (ARect.Right - ARect.Left) / 16;  // 「描画領域 / 16」

  // 縦軸の間隔を設定
  eMeasureY := (ARect.Bottom - ARect.Top) / eGraphDmax;

  // 基準座標設定
  pStart.X := ARect.Left;               // 基準開始 X座標
  pStart.Y := ARect.Top;                // 基準開始 Y座標
  pEnd.X   := ARect.Right;              // 基準終了 X座標
  pEnd.Y   := ARect.Bottom;             // 基準終了 Y座標

  // ---------------------------------------------------------------------------
  // Zoom・シフト有無判定
  // ---------------------------------------------------------------------------
  iZoom    := 1;                     // 簡易増構造にはズーム機能はないので1に指定

  // ---------------------------------------------------------------------------
  // X座標,Y座標取得
  // ---------------------------------------------------------------------------
  for iLoopCnt := 0 to p_Property.iDotNum -1 do
  begin
    // X座標設定
    pDataAry[iLoopCnt].X := pStart.X + Ceil(eMeasureX * iLoopCnt * iZoom);

    // Y座標設定
    pDataAry[iLoopCnt].Y := pEnd.Y - Ceil(eMeasureY * (p_PrintDataAry[iLoopCnt] / 1000) * iZoom);
  end;

  // ---------------------------------------------------------------------------
  // グラフ描画
  // ---------------------------------------------------------------------------
  with ActiveCanvas.Canvas do
  begin
    // 描画線書式設定
    Pen.Style := p_Property.tStyle;     // 線種設定
    Pen.Color := p_Property.tColor;     // 線色設定
    Pen.Width := p_Property.iWidth;     // 線幅設定

    // 描画
    polyLine(pDataAry);
  end;
end;


HOta  2004-01-07 19:30:19  No: 6523

この場合、TPenのWidthが一定以下だと実践になります。この値を少し増やしてみてはいかがですか?


にしの  2004-01-07 19:37:08  No: 6524

BeginPathとEndPathにはさんで描画し、その後、多角形化、Path情報を取得、描画、という具合にします。
単純なMoveTo, LineToでは、DrawPathでうまく行かなかったのですが、polyLineならたぶんうまく行きます。
2点間の場合、PathUtilsの、DrawPathを、次のように変更すれば一応動きました。
    // 図形情報を取り出す
    FirstIndex := LastIndex;
    if FirstIndex + 1 < Path.Count-1 then
    begin
を、
    // 図形情報を取り出す
    FirstIndex := LastIndex;
    if FirstIndex + 0 < Path.Count-1 then
    begin
に。

その上で、

procedure TMainForm.PaintBox1Paint(Sender: TObject);
var
  Path: TPath;
begin
  Path := TPath.Create;
  try
    BeginPath(PaintBox1.Canvas.Handle);
    PaintBox1.Canvas.MoveTo(20,20);
    PaintBox1.Canvas.LineTo(PaintBox1.Width-20, PaintBox1.Height-20);
    EndPath(PaintBox1.Canvas.Handle);

    FlattenPath(PaintBox1.Canvas.Handle);

    Path.LoadFromCanvas(PaintBox1.Canvas);
    DrawPath(Path, PaintBox1.Canvas, clRed, 8, [1, 1]);  // 点線で描く

  finally
    Path.Free;
  end;
end;

こんな感じで出来ました。


にしの  2004-01-07 19:40:21  No: 6525

> 単純なMoveTo, LineToでは、DrawPathでうまく行かなかったのですが
http://www.asahi-net.or.jp/~HA3T-NKMR/DGS/AfterCare.htm#Aftercare10

ここに出てましたね。
こちらに差し替えてください。私の修正だと抜けがあると思いますので。


のり  2004-01-07 19:54:06  No: 6526

> DrawPath(Path, PaintBox1.Canvas, clRed, 8, [1, 1]);  // 点線で描く
のPathとは何でしょうか?

  HelpでTPathで調べても出てこないので分からないのですが^^;
  [1,1]も何なのでしょう?TCapStyle???

DrawPath(???,描画する場所,描画色,ペン幅,???);  // 点線で描く

一点鎖線、二点鎖線の場合はどうなりますか?


にしの  2004-01-07 20:03:38  No: 6527

DHGL 1.2のChapter6を参照してください。
サンプルがあります。

鎖線も、DrawPathの第5引数で指定できます。
詳細は、DHGL 1.2に含まれるヘルプに出ています。


のり  2004-01-07 20:17:49  No: 6528

できました!!

sadoyamaさん、にしのさん、HOtaさん

ありがとうございました!!


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加