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

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

プログラミングについて
ホームページについて
キャドについて
電子カタログについて
書籍・雑誌
イベント
リンク集
【Jw_cad 外部変形】分割点3
前回は外部変形アプリケーション「分割点2」を作成しましたが、「分割開始点が検索出来ませんでした」のメッセージが表示されて実行が出来ないので、指示した点から線上点を算出して、その点を検索開始点にしてはどうか、という御意見がありました。
 
前回説明したように、検索開始点を指示する主な目的は、分割点を算出する最初の線分・円弧・楕円弧の始点又は終点を決定し、そこから連続線の検索及び分割点を算出し作図する、という最初の要素データを取得する事・最初の端点を取得する事、でした。
その際、検索した要素データの端点を全てピックアップし、それらのうち同じ座標があるかどうか(イコール条件)、でチェックを行っていましたが、イコール条件でなくてもOKにする手法としては
・一番近い点を採用する
・一番近い要素データを検索し、どちらの端点側かを判断する
があります。前者の方がおそらくは容易でしょう。
 
点と点との距離計算は、前回も書きましたが、
  d = Sqrt( (x2-x1)2 + (y2-y1)2 )
となります。
 
点と線分との距離計算は、線分の傾き角度を算出し、線分の端点を基準にその角度分、逆回転すると考えます。逆回転された点と、逆回転された水平線との距離は、Y座標の差、という事になります。
 
点と円・円弧との距離計算は、点と円円弧中心点との距離を算出し、半径を引き算し絶対値を施した値となります。
 
点と楕円・楕円弧との距離計算は、まず、楕円楕円弧上の点を求め、2点間の距離を算出すれば良いでしょう。楕円楕円弧上の点は、まず楕円の偏平率で楕円Y半径と点・中心点の差分を割り算し、円の状態と見なします。その状態で点・中心点の角度αを算出します。その場合、楕円楕円弧上の点の座標は、
 x = cx + r * Cos(α)
 y = cy + r * h * Sin(α)
   中心点(cx,cy)、半径 r、偏平率 h
となります。
 
それではまずバッチファイルから。前回とほぼ同じです。
p043_分割点3.bat
REM p043−分割点3
@echo off
REM #jww
REM #cd
REM #hf
REM #zs
REM #zc
REM #zz
REM #zw
REM #1 分割開始点を指示して下さい。(L)free (R)Read
REM #h1
REM #hc 範囲選択をして下さい。
REM #g0
REM #hr
start /w p043.exe
指定した分割開始点に一番近い端点を探します。線分→円弧楕円弧の順・範囲選択で取得出来る要素順に検索しますが、点が重なっている場合や混み入った状態の場合は、思惑と異なる検索・分割点の作図が行われる可能性もありますので御注意下さい。
 

 
プロジェクト「p043」の準備を行います。「C:\DelphiProgram\jww」フォルダの中に「p043」というフォルダを作成し、Windowsのエクスプローラ等で「p042」内のファイルを「p043」の中へコピーします。(※移動しないよう注意)
Delphi6を起動します。メニュー「ファイル」→「プロジェクトを開く」を実行し、「C:\DelphiProgram\jww\p043」内の「p042.dpr」を開きます。メニュー「プロジェクト」→「オプション」を実行し、下記の設定を行います。
[アプリケーション]頁
 タイトル
p043−分割点3
[ディレクトリ/条件]頁
 パス及びディレクトリ
C:\DelphiProgram\jww\p043

メニュー「ファイル」→「プロジェクトに名前を付けて保存」
「C:\DelphiProgram\jww\p043」の中に「p043.dpr」として保存
「C:\DelphiProgram\jww\p043」の中に「p042.〜」のファイルが残っていますので、Windowsのエクスプローラ等で削除します。
プロジェクトマネージャを表示しコード画面の左側にドッキングしておきます。
画面レイアウトを下記のようにしてみました。

開始余白部は、開始点から分割距離計算処理は行うけれども点は表示しないオフセット距離のような感じで指定出来るようにします。初期値は「0」とします。マイナス値は指定出来ないようにします。
 
まずは範囲選択を行った要素データの始点・終点座標をピックアップします。これは前回の「分割点2」と同様です。そして、分割開始点と一番近い端点を検索します。必ずどこかの端点を取得しますので「分割開始点が検索出来ませんでした」のメッセージ表示はありません。
Unit1.pas
(・・・)
  // 分割開始点に一番近い端点を検索
  Label3.Caption := '分割開始点を検索中です';
  Label3.Update ;
  xx1 := JG_IPoints[1].x ;
  yy1 := JG_IPoints[1].y ;
  j := 0;
  l := 0.0;
  for i:=0 to pn-1 do begin
   ll := Dist(xx1,yy1,pnt[i].x,pnt[i].y);
   if (i = 0) then
    l := ll
   else begin
    if (l > ll) then begin
     l := ll ;
     j := i ;
    end;
   end;
  end;
(・・・)
問題は、処理を行う開始点がどこなのかを明確にしておく事です。
1)指定した点からの線上点
2)検索した要素データの該当端点
今回は1)で作りますが、任意点という事は、いい加減な点座標である可能性もある訳です。きちっとした点の場合は端点をスナップ(右クリック取得)すれば良い訳ですが、適当な分割点作図も出来てしまうという事は抑えておく方が良いと思われます。
 
さて、次に線上点を算出する訳ですが、上記の変数 j の端点を持つ要素データが線分か円弧・楕円弧かを取得して、それぞれ計算を行う必要があります。このプログラムでは、円弧と楕円弧の区別を行っていませんので、楕円弧として計算を行います。
Unit1.pas
(・・・)
  // 線上点を取得
  if (pnt[j].t1 = 0) then begin
   // 線分
   with JW_EntLine[pnt[j].n] do begin
    a := Angle(x2-x1,y2-y1);
    rx := RevX(xx1,yy1, x1,y1, -a);
    ry := y1 ;
    xx1:= RevX(rx,ry, x1,y1, a);
    yy1:= RevY(rx,ry, x1,y1, a);
   end;
  end
  else begin
   // 円弧楕円弧
   with JW_EntArc[pnt[j].n] do begin
    Rev(rx,ry, xx1,yy1, cx,cy, -ka);
    ry := (ry-cy)/he + cy;
    a := Angle(rx-cx,ry-cy);
    rx := cx + cr *Cos(a);
    ry := cy + cr*he*Sin(a);
    Rev(xx1,yy1, rx,ry, cx,cy, ka);
   end;
  end;
(・・・)
線上点座標は変数 xx1,yy1 に入れています。上記で「RevX」「RevY」という関数を使っていますが、これは MyFunc.pas で
MyFunc.pas
(・・・)
// 回転x
// x,y :座標
// cx,cy :回転中心座標
// a  :回転角度[rad]
// out :回転後のx座標
function RevX(x,y,cx,cy,a:double):double ;
var
  w : double ;
begin
  w := cx + (x-cx)*Cos(a) - (y-cy)*Sin(a) ;
  Result := w ;
end;
 
// 回転y
// x,y :座標
// cx,cy :回転中心座標
// a  :回転角度[rad]
// out :回転後のy座標
function RevY(x,y,cx,cy,a:double):double ;
var
  w : double ;
begin
  w := cy + (x-cx)*Sin(a) + (y-cy)*Cos(a) ;
  Result := w ;
end;
(・・・)
のように用意しています。関数 Rev もありますが、[rad]のまま計算したい場合やX,Yどちらかだけで良い場合に利用しています。
 
線上点が計算出来ましたので、「□開始点に点を作図する」にチェックをした場合には、点を作図するようにします。任意点の場合、線上点は分からない場合が多いので、デフォルトでこのチェックをオンにしておきます。
Unit1.pas
(・・・)
  // 開始点に点を作図する
  S_LGrp(JG_CurLGrp);  // 現在のレイヤグループ
  S_Lay( JG_CurLay);   // 現在のレイヤ
  S_PCol(JG_CurCol,0);  // 現在の線色
  if (CheckBox1.Checked) then begin
   S_Ten(xx1,yy1);
  end;
(・・・)
最初の要素データが線分の場合は大丈夫ですが、円弧楕円弧データの場合は、分割点がおかしくなってしまいます。これは、xx1,yy1、xx2,yy2の値を使わず、データの sa・ea の角度値を使っているからなので、この辺りを修正しておきます。
 
最終的に表示される「全長」は、線上点から計測しますので、要素データの長さの合計とは異なる値となりますので注意して下さい。
 
余白部については、全長計算は逐次行っていますので、その値よりも短い場合には点を作図しない、という具合にすれば良いと思われます。ちょうど同じ値になる場合には点を作図すれば良いでしょう。
 

 
という訳で、前回と同じく今回も、ソースをオープンにはしません。
 
今回のバッチファイルと実行ファイルについては、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.