2018年9月7日金曜日

Jw_cadの外部変形のデータをC#で処理したら楕円弧の角度がずれてしまい、三角関数での計算が必要とのことで数学的に頑張ったメソッド

Jw_cadに外部変形と言う機能があります。
本来の使い方とは少し違うかも知れませんが、書き出したデータを自作アプリケーション(CamOnLaser)で読み込むことにより連携する処理を作っています。
(Jw_cad --外部変形-> CamOnLaser --USBシリアル通信-> レーザー加工機)

アプリケーションの完成が見えてきて、テストを兼ねた実加工を順調に行っていましたが、一部の加工がずれた…

最外周とその内側が楕円弧です
内側の楕円弧が一見では不規則にカットされている


よくよく調べてみると、Jw_cadが書き出している、楕円弧の開始角度と終了角度が思っていたのと違う。
どうやら、数学的に意味があってこうなっているぽい、らしい。とのことで、三角関数で変換を行いました。

作図した楕円弧は緑の部分
対して、出力されるのは赤の円弧に対応する角度
黒の矢印の経路で必要とする角度を取得
(数式はいろいろ怪しいので省略)


ノートに数式を、しかも三角関数とか20年ぶり位じゃなかろうかと怪しげに書いては直して表計算スプシで確認しつつ1日、その後、実装してしたところカッチリ動いている。想定外だっ・・・
上手くいっています
穴の直径が2mm
6角形の頂点距離(?)2.5mm
肉抜きの結果、残った幅が0.5mm
ここまで拡大すると粗が目立ちますが・・・


/// 楕円に関する角度を取得(変換)する
/// (JWC_TEMP.TXTの角度は外接する正円の座標ベースの角度であるので楕円の場合は変換が必要)
/// ※※ 引数は傾ける前の値が必要 ※※
/// ※※ ごにょごにょ計算した結果、radius(半径)は打ち消されて消滅したが、アレなので引数に含めておく ※※
private float GetEllipseAngle(float radius, float aspectRatio, float angle)
{
    // 引数の確認
    if (radius < float.Epsilon) { return angle; }   // そのまま返す
    
    // 正円(弧)の確認
    if (aspectRatio == (float)1.0) { return angle; }
    
    // 90度単位の確認
    if (angle % (float)90.0 < float.Epsilon) { return angle; }
    
    // 角度の管理
    float temp_angle = angle % (float)360.0;
    
    // 象限の取得(0:第一象限~3:第四象限)
    int quadrant = (int)Math.Floor(temp_angle / (float)90.0);
    
    // 第二象限と第四象限の場合は、半径と扁平率をX方向とY方向で入れ替える
    float temp_radius = radius;
    float temp_aspectRatio = aspectRatio;
    if (quadrant == 1 || quadrant == 3)
    {
        temp_radius = radius * aspectRatio;     // 使用しない
        temp_aspectRatio = (float)1.0 / aspectRatio;
    }
    
    // 角度を第一象限に移動する
    temp_angle = temp_angle - ((float)quadrant * (float)90.0);
    
    // コサインの計算
    float cosA = (float)Math.Cos(temp_angle * Math.PI / (double)180.0);
    
    // 楕円上の座標のタンジェントを計算
    float temp_ret = temp_aspectRatio * (float)Math.Sqrt((float)1.0 - cosA * cosA) / cosA;
    
    // アークタンジェントを取る
    temp_ret = (float)Math.Atan(temp_ret);
    
    // ラジアンから戻す
    temp_ret = temp_ret * (float)180.0 / (float)Math.PI;
    
    // 象限を戻す
    float ret = temp_ret + ((float)quadrant * (float)90.0);
    
    // 返す
    return ret;
}


そういえば、「180」を「(double)180.0」とかしていますが、そんなことをしなくても内部的にdouble型になった後に計算されるはずです。が、覚えておくのが面倒なので明示的にキャストするようにしています。(思考停止)

2018年6月22日金曜日

2018年6月20日水曜日

C#でユーザコントロール側(参照先)からフォーム側(参照元)のメソッドをイベントを介して使用する方法を覚えないで毎度調べているのでメモ

--手っ取り早く済ます方法->

/// フォーム側
namespace HogeSpace
{
    public partial class formHoge : Form
    {
        (中略)
        
        /// ロードされたとき
        private void formHoge_Load(object sender, EventArgs e)
        {
            // ユーザコントロールにイベントハンドラーを設定する
            this.userControlHoge.SetHogeEventHandler += new EventHandler(this.SetHoge);
        }
        
        (中略)
        
        /// ユーザコントロールから使用されるメソッド
        private void SetHoge(object sender, EventArgs e)
        {
            // キャストして確認する
            string str = sender as string;
            if (str  == null) { return; }
            
            // ラベルに表示するとか
            this.lblHoge.Text = str;
        }
    }
}

/// ユーザコントロール側
namespace HogeSpace
{
    public partial class userControlHoge : UserControl
    {
        // イベントハンドラー
        public event EventHandler SetHogeEventHandler = null;
        
        (中略)
        
        /// テキストボックスからフォーカスアウトしたとき
        private void txtHoge_Leave(object sender, EventArgs e)
        {
            // イベントの設定の確認
            if (this.setHogeEventHandler  == null) { return; }
            
            // フォーム側に値を適用する
            this.SetHogeEventHandler (((TextBox)sender).Text, null);
        }
    }
}

<-手っ取り早く済ます方法--


--型を固定したり戻り値を取ったりする方法->

/// フォーム側
namespace PiyoSpace
{
    // イベントの型定義
    // (同じnamespace配下であればどの.csに記載しても大丈夫(のはず))
    public delegate string PiyoEventHandler(int index);    // <-
    
    public partial class formPiyo : Form
    {
        (中略)
        
        /// ロードされたとき
        private void formPiyo_Load(object sender, EventArgs e)
        {
            // ユーザコントロールにイベントハンドラーを設定する
            this.userControlPiyo.GetPiyoEventHandler += new PiyoEventHandler(this.GetPiyo);
        }
        
        (中略)
        
        /// ユーザコントロールから使用されるメソッド
        private string GetPiyo(int index)
        {
            // フォームのリストビューから指定されたインデックスの文字列を返すとか
            string ret = string.Empty;
            try
            {
                ret = this.listViewPiyo.Items[i].ToString();
            }
            catch
            {
                ret = string.Empty;
            }
            
            return  ret;
        }
    }
}

/// ユーザコントロール側
namespace PiyoSpace
{
    public partial class userControlPiyo : UserControl
    {
        // イベントハンドラー
        public event PiyoEventHandler GetPiyoEventHandler = null;
        
        (中略)
        
        /// コンボボックスの選択が変更されたとき
        private void cmbPiyo_SelectedIndexChanged(object sender, EventArgs e)
        {
            // イベントの設定の確認
            if (this.getPiyoEventHandler == null) { return; }
            
            // 選択しているインデックスを取得する
            int index = ((ComboBox)sender).Selectedindex;
            
            // フォーム側から値を取得する
            string str = this.GetPiyoEventHandler (index);
            
            // ラベルに表示してみるとか
            this.lblPiyo.Text = str;
        }
    }
}

<-型を固定したり戻り値を取ったりする方法--


動作しているコードからコピー/編集しました
※編集後のコンパイル/動作確認は行っていません

2018年3月16日金曜日

ジャンクの Xperia XZ に替えたら音ズレが出ていることに気がついて焦ったけれど、NFCとノイズキャンセリングをOFFったら直ったぽい

<前   次>

ジャンクで買ってきた Xperia XZ、撮れてる撮れてるうひゃひゃひゃ、って浮かれていたら、音ズレしていることに気がつきました。

動画の内容によっては気がつかないもんで、たぶん音ズレしているはずなのだけれど最初の2つの動画は気がつかなかった。


音ズレに気がつかなかった動画(1)
今見ても分からない

音ズレに気がつかなかった動画(2)
これは気付きようも無い…

なんか変だなと思った動画
駅ビルに音が反射しているのかと思ったのですが違ったみたい
初EH200だったのに…

まじまじと確認して音ズレを確信した動画
ドアの閉まる音が合っていないですね


「ジャンク」ってのが頭にあるので、これは駄目か…、と思ったのですが、Googleったら2013年頃の情報で「CPU負荷を下げるために通信関係を off にして動画撮影すべし」って情報をGet。
ここからヒントを得て ON/off を試してみました。

※バイノーラル録音 = ノイズキャンセリングイヤホンのマイクで録音

バイノーラル録音、ノイズキャンセリング=ON、NFC=ON
どうやって確認しようかと悩んだ結果、こうなりました
すごいずれ

バイノーラル録音、ノイズキャンセリング=ON、NFC=off
少し良くなった

バイノーラル録音、ノイズキャンセリング=off、NFC=ON
だいぶ良くなった

バイノーラル録音、ノイズキャンセリング=off、NFC=off
これなら問題ない

本体マイク、NFC=ON
やっぱりノイズキャンセリングの影響は大きい模様

本体マイク、NFC=off
NFCも切っておくに越したことはなさそう


「ノイズキャンセリング=off」でほとんど大丈夫になって「NFC=off」でもう少し良くなった、感じです。
処理が追いつかないで画像が遅れていた?
スマホで動画撮影のアレなところですかねー


<前   次>



スマホの温度をウィジェットでホーム画面に表示するアプリ「電池の残量と温度」が思ったより10倍くらい便利

<前   次>

気温の上昇に伴い、Xperia Z3 での動画撮影が厳しくなってきたので、秋葉原でジャンクの Xperia XZ を見つけて購入して来ました。
ジャンクの訳は「ゴーストタッチ」が激しく出るというもので、どうやら端末温度に依存する模様。

なのでAndroidアプリをいろいろ試して「電池の残量と温度」と言うウィジェットで温度の確認をしながら使っています。
今のところ上手く使えています。
アプリアイコン 

ウィジェット。こちらのスクリーンショットは訳有って Xperia Z3 で取得しました

さっそく「ホームグラウンドになっている1、2番線ホームの東端」でテストも兼ねて撮影
(ジャンク Xperia XZ に替えてみた) 安中貨物、2018/3/15、牽引EH500-57、タキ8両、トキ5両、通過(48km/hr)。バイノーラル録音+α
気のせいかも知れないけれど、Z3 での撮影に比べて、動画の動きが少しスムース?

Xperia Z3 で撮影した似た構図の動画
逆に言えば進歩が見られるということで


Xperia XZ2 が出たら移行するつもりなので、谷まで持てば 夏前まで持ってくれればうれしい、と言うわけです。
ジャンクなので普通の中古の1/3程度の値段でした。あひゃひゃひゃ
このまま高笑いしつつ逃げ切るか、安物買いの銭失いになるのか、今はまだ分からない。


<前   次>

2018年3月13日火曜日

遅れが出たときの安中貨物に関する状況

<前   次>

2018/3/11、水戸駅で信号点検(時刻分からず)を行ったとの事で一部列車に遅れがあった。
撮影地は水戸から90kmほど上野寄り。

見た範囲において、
・E231系(快速)は0~5分の遅れ
・E531系(特別快速、快速)は0~10分の遅れ
E657系(特急)は0~30分の遅れ
安中貨物は60分の遅れ
でした。

安中貨物が30分を過ぎても来ない辺りで運休を疑ったのですが、運休になったら工場が困るはずだと思ってネバってたら、60分遅れにて普段より少し早足な感じでやって来ました。旅客列車よりかなり影響を受けるみたいです。(たぶんゆずったりゆずったりゆずったり)

なので、遅延が発生している場合は、「相当待てばたぶん来る」と思うのが良さそうです。寒かったり極端に暑かったりするとつらい。。。
(貨物列車を撮影した動画を見ると、「xxでxx時間遅延」ってたまに書いてある意味と気持ちが良ーく分かった)


特別快速、E531系、4分遅れ
雰囲気的には普段と変わりなし

快速、E231系、5分遅れ
特急に煽られてつらい感じ

特急、E657系、27分遅れ
ひたち14号
快速につかえてつらい感じ

特急、E657系、3分遅れ
ときわ76号
勝田(水戸の隣)始発なのが関係してか、もしくはタイミングの問題なのかあんまり影響ない感じ

安中貨物、57分遅れ
亜鉛工場の人たちの残業が気になる


<前   次>

2018年3月11日日曜日

車両形式の「系」と「形」

<前   次>

沿線がJR東日本なので、「E231系」「E657系」など「系」になじみが深いのです。
小田急の4000形が3社相互乗り入れで顔を出すのですが、先ほどまで「小田急4000系」になっていた。。。
(慌てて直した)

鉄ヲタ歴は長いのですがいかんせんユルイもので、何が違うんやねん、て言うて調べました。


ほほう。車両単体では「形」だけれど編成として「系列で組んで」運用する場合、ま、すなわち主に電車なのですが「系」と呼ぶように変化したと。
そのときに「形」を「系」に変更しないで「形」のまま使っている会社もあると。

なるほどー

ご幼少のみぎりには小田急1000形が綾瀬で折り返しだったのであんまりなじみがなかっ…、あっ、従兄弟が小田急に勤めているような気もしなくもないぞ。

で、小田急4000形はJR東日本のE233系をベースにしていますが、VVVFの音が違うような、気がしなくも無い今日この頃です。


小田急4000形


JR東日本E233系2000番台


気のせい??
(分からなくなってきた)


<前   次>