AFsoft WebSite(エーエフソフト・ウェブサイト)
 

オペレーティング・システムについて

プログラミングについて
ホームページについて
キャドについて
電子カタログについて
書籍・雑誌
イベント
リンク集
【Jw_cad 外部変形】矩形を作図する(3)
矩形を作図の続きを行います。プロジェクト「p023」の準備を行います。「C:\DelphiProgram\jww」フォルダの中に「p023」というフォルダを作成し、Windowsのエクスプローラ等で「p022」内のファイルを「p023」の中へコピーします(※移動しないよう注意)
Delphi6を起動します。メニュー「ファイル」→「プロジェクトを開く」を実行し、「C:\DelphiProgram\jww\p023」内の「p022.dpr」を開きます。メニュー「プロジェクト」→「オプション」を実行し、下記の設定を行います。
[アプリケーション]頁
 タイトル
p023−矩形を作図
[ディレクトリ/条件]頁
 パス及びディレクトリ
C:\DelphiProgram\jww\p023

メニュー「ファイル」→「プロジェクトに名前を付けて保存」
「C:\DelphiProgram\jww\p023」の中に「p023.dpr」として保存
「C:\DelphiProgram\jww\p023」の中に「p022.〜」のファイルが残っていますので、Windowsのエクスプローラ等で削除します。

「p023」で実行するバッチファイルは「p022」とほぼ同じなので「p022」で書き出されるデータファイル「JWC_TEMP.TXT」を読み込む事を考えます。以下のような内容となります。
hq
hk 0
hs 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 1
hzs 1189 841
hcw 2 2.5 3 4 5 6 7 8 9 10
hch 2 2.5 3 4 5 6 7 8 9 10
hcd 0 0 0.5 0.5 0.5 1 1 1 1 1
hcc 1 1 2 2 3 3 4 4 5 5
hn 35890.866873065 -22270.7430340557 35890.866873065 -22270.7430340557
lg0
ly0
lc2
lt1
lw0
cn3
cn"$<MS ゴシック>
#
ファイルの開き方は既に説明しましたので、読み込んだ1行を解析し、変数にその内容を格納する事を考えます。これを行う専用のユニットを作る事にします。ですので、メニュー「ファイル」→「新規作成」→「ユニット」を実行します。コード画面にその新しいユニット Unit2.pas の内容が表示されます。(※以下では全角空白を付けて桁調整等をしていますが実際は半角空白或いは無しです)
unit Unit2;
 
interface
 
implementation
 
end.
取りあえずそのままメニュー「ファイル」→「名前を付けて保存」で「JwwGaibu.pas」として保存します。Unit1からこのユニットを利用するようにします。uses節に「JwwGaibu」を追加します。
ファイルが増えてくるとどんなファイルがあったのかを確認したり別のファイルを見たりする為、メニュー「表示」→「プロジェクトマネージャ」を実行します。

この画面はコード画面の左側へドラッグ&ドロップでドッキングさせておくと利用しやすいかもしれません。

 
Unit1.pas に少し追記を行います。「p022」を「p023」に変えておきます。
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls,
  MyFunc, JwwGaibu ;
 
type
(・・・中略・・・)
// 起動時
procedure TForm1.FormShow(Sender: TObject);
var
  F : TextFile ;
  s : string ;
begin
  OKflag := False ;
  Xsize := 0.0 ;
  Ysize := 0.0 ;
  ALmode := 2 ;
  // プログラムのあるフォルダを取得します
  AppPath := ExtractFilePath(Application.ExeName) ;
  // 位置情報等を読み込み
  if (FileExists(AppPath+'p023.dat')) then begin
   try
    AssignFile(F, AppPath+'p023.dat');
    FileMode := 0;
    Reset(F);
    ReadLn(F, s);   Form1.Left := SInt(s);
    ReadLn(F, s);   Form1.Top := SInt(s);
    ReadLn(F, s);   Xsize := SDbl(s);
    ReadLn(F, s);   Ysize := SDbl(s);
    ReadLn(F, s);   ALmode:= SInt(s);
    CloseFile(F);
   except
    CloseFile(F);
   end;
  end;
  Edit1.text := FloatToStr(Xsize);
  Edit2.text := FloatToStr(Ysize);
  RadioGroup1.ItemIndex := ALmode;
  // JWC_TEMP.TXTを開きます
  OpenTempFile(AppPath+'JWC_TEMP.TXT') ;
end;
(・・・後略・・・)
JwwGaibu.pasの方は取りあえず以下のように書いておきます。uses節の「SysUtils」は FileExists関数を使うのに必要となります。
unit JwwGaibu;
 
interface
 
uses
  SysUtils, MyFunc ;
 
  function OpenTempFile(fn:string) : Boolean ;
 
implementation
 
// Jw_cad 外部変形
// 書き出しデータ「JWC_TEMP.TXT」を読み込む
//  fn : ファイル名(フルパス)
// (ret)
//  True : OK  False : Error
function OpenTempFile(fn:string) : Boolean ;
var
  F : TextFile ;
  s : string ;
begin
  Result := False ;
  if not(FileExists(fn)) then exit;
  try
   AssignFile(F, fn);
   FileMode := 0;
   Reset(F);
   while not(Eof(F)) do begin
     ReadLn(F, s);
  (・・・読み込み部・・・)
   end;
   CloseFile(F);
   Result := True ;
  except
   CloseFile(F);
  end;
end;
 
end.
Eof関数は、ファイルを最後まで読み込むと True を返します。途中の場合は False を返します。ですので、while文でファイルの最後まで読み込むよう繰り返しています。上記の(読み込み部)で、読み込んだ1行の文字列を解析して変数に入れるという処理を記述するのですが、複雑になる事が予想されますので、その解析部分は手続きにして別々にします。
unit JwwGaibu;
 
interface
 
uses
  SysUtils, MyFunc ;
 
  function OpenTempFile(fn:string) : Boolean ;
 
implementation
 
// JWC_TEMP.TXT 読み込み解析部
procedure GetTempCode(codes:string);
begin
  ;
end;
 
// Jw_cad 外部変形
// 書き出しデータ「JWC_TEMP.TXT」を読み込む
//  fn : ファイル名(フルパス)
// (ret)
//  True : OK  False : Error
function OpenTempFile(fn:string) : Boolean ;
var
  F : TextFile ;
  s : string ;
begin
  Result := False ;
  if not(FileExists(fn)) then exit;
  try
   AssignFile(F, fn);
   FileMode := 0;
   Reset(F);
   while not(Eof(F)) do begin
     ReadLn(F, s);
     GetTempCode(s);
   end;
   CloseFile(F);
   Result := True ;
  except
   CloseFile(F);
  end;
end;
 
end.
こうしておけば、1行読み込んで○○して・・・という○○の部分だけを GetTempCode内に書けば良いです。なお、OpenTempFileよりも先に書いているのはDelphi=Pascalが前方参照であるからですが、下(後)に書きたい場合は上部で宣言すれば良いのですが、外部から呼び出す関数・手続きと混乱してしまうため避けています。(※クラス化すれば private節で宣言すると良いです)
 
JWC_TEMP.TXT の各行は、半角空白で区切られています。ですのでまず半角空白で区切ってバラバラに変数に入れる事を考えます。その変数の個数は何個になるのか分かりませんので、動的配列を使う事にします。
受け取った文字列の長さを取得して、1文字ずつチェックし、半角空白があれば〜という感じになりますが、もし漢字等の全角文字(2バイト系文字)が来た場合、ひょっとすると制御文字が入ってしまった場合、文字「"」が来た場合、というような事も考えて処理します。「"」が来た後の半角空白は区切り文字ではありません。
// JWC_TEMP.TXT 読み込み解析部
procedure GetTempCode(codes:string);
var
  pa : array of string ;
  i,j,n : integer ;
  mflag : Boolean ;
begin
  if (codes = '') then exit ;
  SetLength(pa,32) ; // 多めにメモリ確保しておきます
  for i:=0 to 31 do
   pa[i] := ''; // 内容を初期化します(空状態)
  // 半角空白を区切りとして分解
  i := 1 ;
  j := 0 ;
  n := Length(codes) ;
  mflag := True ;
  while(i <= n) do begin
   if (Ord(codes[i]) >= 128)and(Ord(codes[i]) <= 159)
   or(Ord(codes[i]) >= 224)and(Ord(codes[i]) <= 253) then begin
    if ((i+1) > n) then break ; // エラー
    // 全角文字
    pa[j] := pa[j] + codes[i] + codes[i+1] ;
    Inc(i);
   end
   else if (codes[i] = '"')and(mflag) then begin
    mflag := False ; // 「"」以降は文字:空白は区切りにならない
   end
   else if ((codes[i] = ' ')or(codes[i] = #9))and(mflag) then begin
    // 区切り文字
    if (pa[j] <> '') then
     Inc(j); // 半角空白が2つ以上の場合への処置
   end
   else if (Ord(codes[i]) < 32)or(Ord(codes[i]) > 253) then begin
    // 制御コードの場合は何もしない
   end
   else begin
    // 半角文字
    pa[j] := pa[j] + codes[i] ;
   end;
   Inc(i);
  end;
  n := j + 1;   // 数
  if (n = 1)and(pa[0] = '') then begin
   pa := nil ;
   exit ;
  end;
  // 各設定内容の読み込み
  if (pa[0] = 'hk')and(n >= 2) then begin
   // 軸角
   JG_Jikukaku := Sdbl(pa[1]) ;
  end;
 
  pa := nil; // メモリ解放します
end;
取りあえず軸角「hk」の値を変数 JG_Jikukaku に入れます。この変数は冒頭部で変数宣言を行い、初期化処理も入れておきます。
unit JwwGaibu;
 
interface
 
uses
  SysUtils, MyFunc ;
 
var
  JG_Jikukaku : double ;  // 軸角[°]
 
  function OpenTempFile(fn:string) : Boolean ;
 
implementation
(・・・中略・・・)
function OpenTempFile(fn:string) : Boolean ;
var
  F : TextFile ;
  s : string ;
begin
  // 各設定内容の初期化
  JG_Jikukaku := 0.0 ;  // 軸角[°]
 
  // 読み込み
(・・・後略・・・)
 
次に、軸角による回転処理を考えます。回転処理=写像は、回転の中心点が(0,0)の場合
  x = X*Cos(ang) - Y*Sin(ang)
  y = X*Sin(ang) + Y*Cos(ang)
となります。回転中心点が(cx,cy)である場合には
  x = cx + (X-cx)*Cos(ang) - (Y-cy)*Sin(ang)
  y = cy + (X-cx)*Sin(ang) + (Y-cy)*Cos(ang)
となります。
これを行う手続きを MyFunc.pas に用意します。プロジェクトマネージャ内の「MyFunc.pas」をダブルクリックすると、コード画面に表示されます。以下を追加します。
宣言部
procedure Rev(var rx,ry:double;x,y,cx,cy,a:double) ;
実装部
// 回転
// rx,ry : 回転後の座標
// x ,y : 座標
// cx,cy : 回転中心座標
// a   : 回転角度[°]
procedure Rev(var rx,ry:double;x,y,cx,cy,a:double) ;
var
  an : double ; // ラジアン値
begin
  an := a/180.0*Pi ;
  rx := cx + (x-cx)*Cos(an) - (y-cy)*Sin(an) ;
  ry := cy + (x-cy)*Sin(an) + (y-cy)*Cos(an) ;
end;
Unit1.pasの TForm1.FormClose〜のJWC_TEMP.TXT保存部分を書き換えます。作業用変数 w1,w2,w3,w4 : double も追加しておきます。
(・・・前略・・・)
x2 := x1 + Xsize;
y2 := y1 + Ysize;
Rev(w1,w2, x1,y1, 0.0,0.0, JG_Jikukaku);
Rev(w3,w4, x2,y1, 0.0,0.0, JG_Jikukaku);
s := FloatToStr(w1) + ' ' + FloatToStr(w2) + ' ' + FloatToStr(w3) + ' ' + FloatToStr(w4);
WriteLn(F, s);
w1 := w3 ;
w2 := w4 ;
Rev(w3,w4, x2,y2, 0.0,0.0, JG_Jikukaku);
s := FloatToStr(w1) + ' ' + FloatToStr(w2) + ' ' + FloatToStr(w3) + ' ' + FloatToStr(w4);
WriteLn(F, s);
w1 := w3 ;
w2 := w4 ;
Rev(w3,w4, x1,y2, 0.0,0.0, JG_Jikukaku);
s := FloatToStr(w1) + ' ' + FloatToStr(w2) + ' ' + FloatToStr(w3) + ' ' + FloatToStr(w4);
WriteLn(F, s);
w1 := w3 ;
w2 := w4 ;
Rev(w3,w4, x1,y1, 0.0,0.0, JG_Jikukaku);
s := FloatToStr(w1) + ' ' + FloatToStr(w2) + ' ' + FloatToStr(w3) + ' ' + FloatToStr(w4);
WriteLn(F, s);
(・・・後略・・・)
 
メニュー「ファイル」→「すべて保存」を行い
メニュー「プロジェクト」→「再構築」を行いエラー表示されない事を確認して下さい。
 
 
Windowsのメモ帳やテキストエディタ等を利用し、フォルダ「Gapp」内に以下のようなバッチファイルを作成します。
p023_矩形を作図(3).bat
REM p023−矩形を作図(3)
@echo off
REM #jww
REM #cd
REM #zs
REM #zw
REM #0配置点を指示して下さい。(L)free (R)Read
REM #hr
start /w p023.exe
Windowsのエクスプローラ等で、「C:\DelphiProgram\jww\p023」内にある「p023.exe」をフォルダ「Gapp」内へコピーします。
 
Jw_cad を起動し、何か作図してある状態で
メニュー→その他→外部変形
「ファイル選択」画面でフォルダ「Gapp」を指定し、上記で作成したバッチファイル「p023_矩形を作図(3).bat」を実行します。

バッチファイルで指定したように「配置点を指示して下さい」と表示されますので、矩形を作図する点を指示します。

コマンドプロンプト画面が表示されて、上記で作成した外部変形プログラム「p023.exe」=「p023−矩形を作図(3)」が起動されます。

数値を入力して配置モードを指定し[OK]をクリックします。軸角指定無しの場合=軸角0°の場合は、下記のように矩形が作図されます。

軸角を30°にしてみます。

矩形を作図する点を指示します。

コマンドプロンプト画面が表示されて、外部変形プログラム「p023.exe」=「p023−矩形を作図(3)」が起動されます。配置モードを左下に変えてみます。

下記のように矩形が作図されます。
軸角が30°ですので矩形も30°傾いて作図されます。

以上で、オリジナルの外部変形アプリケーション「矩形を作図(3)」が作成出来ました。
 
 
今回のバッチファイルと実行ファイル、及び、ソースファイルについては、Pcataサイトに置いておきますので必要な方はそちらからダウンロードして下さい。
 
 
CAD装置(1)
CAD装置(2)
メディア
AutoCADの
DIESELマクロ
CSV
DXF
PCES
IGES
STEP
数学とCAD
CAD作ろ!
M7
Jw_cad
 [BACK]
 [NEXT]
 
お問い合わせ 
本サイトはリンクフリーです
リンクバナー
(C)Copyright 1999-2015 By AFsoft All Rights Reserved.