Re: \arcと同じオプションで点線の円弧を描く

名前: .
日時: 2005-07-20 22:18:00
IPアドレス: 220.214.19.*

>>36966 # 簡単だと断言した以上,そうでないと困りますので とりあえず,実装例を挙げます. やはり,基本的な四則演算・条件処理(ループ処理を含む)の範囲で済みます (先の \dottedarc の処理と大差ないことが見てとれることでしょう). ただ,処理の仕方(内部の計算に用いるレジスタの使い回し方)によっては, 内部処理に現れる \arc(eepic パッケージによるもの)をグループ内に 閉じ込める必要があるかもしれません(“実際に手を動かさないとわからない” 点はこの点のみです). \@testopt,\strip@pt,\zap@space といったものは,LaTeX でのマクロ作成の “慣用句”で,こういったものについてはファイル latex.ltx(あるいは, 然るべき解説書)を参照してください. \documentclass{article} \usepackage{epic,eepic} \makeatletter \def\dashedarc{\@testopt\@dashedarc{}} \def\@dashedarc[#1]#2#3#4{% %%% #1: 破線の形式の指定: L または L,B の形式 %%% ただし,L は実線部分の長さ,B は空白部分の長さ %%% (ともに \unitlength を単位とする正の実数値)で, %%% 単に L のみを与えた場合には L = B として扱い, %%% オプション引数 #1 を与えない場合には L = B = 5 として扱います. %%% #2: 直径,#3: 開始角,#4: 終了角(#4 > #3) \edef\@tempa{\zap@space#1 \@empty}% \expandafter\@dashedarc@set@pattern\@tempa,,\@nil{#2}% \dimen@ii#4\p@ \dimen@\dimen@ii \advance\dimen@-#3\p@ \ifdim\dimen@>6.2831853\p@%%% 1 回転を超える場合 \dimen@ii#3\p@ \advance\dimen@ii 6.2831853\p@ \fi %%% この時点で \dimen@ii = 破線の円弧全体の終了角 %%% 以下のループ処理の間,\dimen@ = 実線部分の小円弧の開始角 %%% \@tempdimc = 実線部分の小円弧の終了角 \dimen@#3\p@ \@tempdimc\dimen@ \advance\@tempdimc\@tempdima \@whiledim\dimen@<\dimen@ii\do{% \ifdim\@tempdimc>\dimen@ii \@tempdimc\dimen@ii \fi \edef\@tempa{\noexpand\arc{#2}{\strip@pt\dimen@}{\strip@pt\@tempdimc}}% \begingroup \@tempa%%% 小円弧の出力 %%% \arc も \@tempdima, \@tempdimb を用いているので(cf. eepic.sty), %%% \arc による \@tempdima, \@tempdimb の変更をグループ内に %%% 閉じ込めます.もちろん,\dashedarc の処理に用いる各種の寸法 %%% (あるいは実数)を保存するための専用の \dimen レジスタを %%% 割り当てて,それを用いるようにすると,内部処理で用いた %%% \arc をグループ内に閉じ込めるようなことをしなくても済みます. \endgroup %%% 各パラメータを次の小円弧に対応する値に更新 \advance\dimen@\@tempdimb \advance\@tempdimc\@tempdimb}} \def\@dashedarc@set@pattern#1,#2,#3\@nil#4{%%% #4: 直径 %%% \@tempa: 実線部分の小円弧の長さ(\unitlength 単位の数値) %%% または 空文字列 \def\@tempa{#1}% %%% \@tempb: 空白部分の長さ(\unitlength 単位の数値)または 空文字列 \def\@tempb{#2}% \ifx\@tempa\@empty \def\@tempa{5}\fi \ifx\@tempb\@empty \let\@tempb\@tempa \fi \@tempdima\@tempa\unitlength \ifdim\@tempdima>\z@\else \@tempdima=5\unitlength \fi \@tempdimb\@tempb\unitlength \ifdim\@tempdimb>\z@\else \@tempdimb=5\unitlength \fi \advance\@tempdimb\@tempdima \dimen@#4\unitlength \ifdim\dimen@>\p@\else \dimen@=\p@ \fi%%% ゼロ除算の回避 %%% 数値オーバーフローの回避((*) までの部分) %%% “分子が 64 未満となるように分母・分子を 2 で割り続ける”処理 \ifdim\@tempdima>\@tempdimb \dimen@ii\@tempdima \else \dimen@ii\@tempdimb \fi \@whiledim\dimen@ii>63.99\p@\do{% \divide\@tempdima\tw@%%% \tw@ = 2 \divide\@tempdimb\tw@ \divide\dimen@\tw@ \divide\dimen@ii\tw@}%%% (*) \multiply\@tempdima\@cclvi%%% \@cclvi = 256 \multiply\@tempdimb\@cclvi \divide\dimen@ 512\relax%%% 直径から半径に換算したのち 1/256 倍 \divide\@tempdima\dimen@%%% \@tempdima = 実線部分の小円弧の中心角 \divide\@tempdimb\dimen@%%% \@tempdimb = ある小円弧から次の小円弧までの回転角 \ifdim\@tempdimb>\z@\else \@tempdimb=1sp \fi} %%% \@tempdima = x [pt], \dimen@ = y [pt] = 65536y [sp] のとき %%% 単純に \divide\@tempdima\dimen@ とすると計算後の \@tempdima の値は %%% x/(65536y) [pt] となります.これを 65536 倍すれば x/y [pt] が得られるので, %%% ここでは分子を 256 倍にし,分母を 1/256 にしたのち,除算を実行しています. %%% picture 環境の中で用いる数値の計算ではこの程度でもいいでしょうが, %%% 正確な計算を行いたい場合にはもちろん,もっとまじめな方法で %%% 除算を行うことになります(cf. 『LaTeX 自由自在』4.3.3 項). \makeatother \begin{document} \begin{picture}(100,100) \put(50,50){\circle*{1}} \put(50,50){\arc{40}{0}{0.78}} \put(50,50){\dashedarc[3]{60}{0}{1.57}} \put(50,50){\dashedarc[4,1.5]{80}{0}{2.35}} \put(50,50){\dashedarc{100}{0}{3.14}} \thicklines \put(50,50){\dashedarc[.05,3.09]{20}{0}{6.28}} \end{picture} \end{document}

この書き込みへの返事:

お名前
題名 
メッセージ(タグは <a href="...">...</a> だけ使えます)