vim・viを使ってとりあえず文章を編集する方法
最初に知っておくべきこと
- 動作のわからないキー入力をするとたいてい悲惨なことになるので、してはいけない。
- 特にバックスペースキーはうっかり押して混乱する危険が高い。
- 状態が混沌としてvimを強制終了させたくなったら、エスケープキー連打した後に「:q!」と入力し、エンターキー押せば大体終了してくれる。
- 起動時に編集するテキストファイル名を指定する。`vim some_text.txt`のような感じで。
モードについて
- vimには複数のモードがある。
- モードが違うとキー操作もがらりと変わるので、今どのモードなのかを常に意識しないといけない。
- テキスト編集に最低限必要なのは「コマンドモード」と「挿入モード」の2つ。
- 注:コマンドモードを「ノーマルモード」や「編集モード」、挿入モードを「入力モード」や「編集モード」と呼ぶこともある。
- vim起動直後はコマンドモードになっている。
- コマンドモードのときにiキーを押すと、挿入モードに移る。
- 挿入モードのときにエスケープキーを押すと、コマンドモードに移る。
- 文字以外のキー(例えばカーソルキー)を入力したときもコマンドモードに移動することがあるので注意。
- どんなモードのときでもエスケープキーを押するとコマンドモードに移れるので、路頭に迷ったらエスケープキーを押そう。
- モードごとでできること・できないことは次の通り。
モード名 コマンドモード 挿入モード このモードにするためのキー エスケープキー iキー できること カーソルの移動(h, j, k, lキー)
文字の削除(xキー)
元に戻す(uキー)
vimの終了(「:q」コマンド)
その他色んなコマンド文字の入力。
キーボードの文字を大体普通に打つことができる。
shiftキー押せば通常通り大文字になる。
日本語はcygwin bash上ではMSのIMEが使えてるけど、その他環境は知らない。できないこと 文字の入力
範囲選択文字入力と、カーソル移動以外全部
(vimなら、.vimrcをいじくれば文字の削除はできるようになる)
コマンドについて
- コマンドモードでは、コマンドが使える。
- 以下の説明は全てコマンドモードで行っていることが前提。
- カーソルを移動するには、h, j ,k, lキーを押す。
- カーソルキーも多くの場合使えるが、viでは使えないこともある。
- カーソルの動き方は以下の表の位置のようになる。
j(↑) h(←) l(→) k(↓)
- 文字を削除するには、x, X, dd, Jコマンドを押す。
- xキーを押すと、カーソルの右側の1文字を消す。改行を削除しないことを除いて、windowsのメモ帳でデリートキーを押したときと同じ効果。
- Xキー(shift+x)を押すと、カーソルの左側の1文字を消す。改行を削除しないことを除いて、windowsでバックスペースキーを押したのと同じ効果。
- 「dd」と押すと、カーソルを含む行全体を削除(切り取り)。
- Jキー(shift+j)を押すと、カーソルを行の末尾に移動しつつ、行末の改行を削除する。
- vimを終了するには、コマンドモードで「:q」と押す。このときファイルが更新されていて、かつ保存されていないと、失敗する。
- ファイルを保存せずに終了…「:q!」
- ファイルを上書き保存して終了…「:wq」
- ファイルを上書き保存…「:w」
他のコマンド
- 「dd」コマンドで、一行切り取り。
- pキーで、貼り付け。
- あとは「vim コマンド 一覧」とかでぐぐってください・・・・
3D空間で回転・向きを表す方法
行列
- 回転を行列の掛け算で表せるので、計算が速い
- 行列なので平行移動・拡大縮小・傾きも表現できる
- OpenGLの回転表現法がこれなので、わざわざ変換する必要がない
- 向きを表すのに16個の実数値が必要なので、メモリ効率が悪い
-
- 3D物体1つだとなんてことはない差だが、何万個も物体があると大差に。
- 乗算が多いので、誤差がたまりやすい
オイラー角
- 向きを直観的な形式で表現することができる
- 各軸に対する回転処理が単純かつ高速
- 3つの実数値があればいいので、メモリ効率がいい
- 単純でない回転を適用する場合、計算が複雑で時間がかかる
- 特異点が存在する。つまり、2つの等価でないオイラー角が同じ向きを表すことがある
-
- このためオイラー角が一意に定まらないことを考慮しないといけないので、他の向き表現からの変換が多少複雑。
- ジンバルロックが発生する。つまり、特定の向きのときに回転が急激になったり、ほとんど回転しないことがある。
- 軸の回転順序に自由度があるうえ、状況によって有効な順番が異なるので、統一感がなく紛らわしい
- いくつか流儀がある(参考:RfLab.Wiki - 数学)。
- zxy:航空機の姿勢制御(ロールピッチヨー)。
- yxz:カメラの向き制御
- zxz:ロボットの姿勢制御。狭義のオイラー角。
- xyz:あまり使わないが、順序がわかりやすいので他の向き表現形式からの変換過程で使ったり
クォータニオン
- 回転を四元数の積で表すことができるので、計算が速い
- 拡大縮小も表現できる
- 正規化すると拡大情報が消え、正規化しないと回転の誤差がたまるので、あまり使い勝手がよくないが。
- 2つの向き間の角度を求めるのが高速
- 高速な球面線形補間(Slerp)が使える
- 表現が直観的でない
- 複数回の回転を表現できない。つまり、60度の右回転・420度の右回転・300度の左回転…が、全て等価に扱われる
- 1フレームごとならストロボ効果で気にならぬ
- Slerpとかするときは処理を細かくわけましょう
Androidで縦向き(Portrait)でカメラを使う方法 (主にAndroid2.x向け)
縦向きカメラを使うのは意外に難しい。
要点
- Androidのカメラは横向きが基本。
- Android2.1以前では、縦向きカメラが使用できるかどうかは実装依存。Camera.Parameters.set("rotation", 90); とすると、一部端末で縦向き表示になる。
- Android2.2以降では、Camera.setDisplayOrientation(int)を使うことで縦向きにすることができる。
- 縦向きカメラを使ってもCamera.takePicture()を使って得られた画像は横向きのままなので、手動で変換する必要がある。
カメラを使う
mCamera = Camera.open(); //カメラを用意 mCamera.setPreviewDisplay(holder); //カメラ画像を表示先を設定 mCamera.startPreview(); // カメラ画像の表示を始める mCamera.takePicture(listener, listener, listener, listener); //写真を撮る
カメラを縦向きにする
public static void setCameraDisplayOrientation(Activity activity, int cameraId, android.hardware.Camera camera) { android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo(); android.hardware.Camera.getCameraInfo(cameraId, info); int rotation = activity.getWindowManager().getDefaultDisplay() .getRotation(); int degrees = 0; switch (rotation) { case Surface.ROTATION_0: degrees = 0; break; case Surface.ROTATION_90: degrees = 90; break; case Surface.ROTATION_180: degrees = 180; break; case Surface.ROTATION_270: degrees = 270; break; } int result; if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { result = (info.orientation + degrees) % 360; result = (360 - result) % 360; // compensate the mirror } else { // back-facing result = (info.orientation - degrees + 360) % 360; } camera.setDisplayOrientation(result); }
撮影した写真を縦向きにする
- Canvas.rotate()とCanvas.drawBitmap()を使い、回転処理をしたミュータブルなBitmapを新たに作る
- Bitmap.createBitmap(Bitmap, int, int, int, int, Matrix, boolean)を使い、回転処理をしたイミュータブルなBitmapを新たに作る
- ndkのAndroidBitmap_lockPixelsからピクセルデータを置き換える
- 写真をJPEG形式で保存し、Exifに向き情報を付加する
int degrees = getCameraDisplayOrientation(this); // 後述のメソッド Matrix m = new Matrix(); m.postRotate(degrees); Bitmap rotatedBitmap = Bitmap.createBitmap(origBitmap, 0, 0, origBitmap.getWidth(), origBitmap.getHeight(), m, false);
public static int getCameraDisplayOrientation(Activity activity) { int rotation = activity.getWindowManager().getDefaultDisplay().getRotation(); int degrees = 0; switch (rotation) { case Surface.ROTATION_0: degrees = 0; break; case Surface.ROTATION_90: degrees = 90; break; case Surface.ROTATION_180: degrees = 180; break; case Surface.ROTATION_270: degrees = 270; break; } return (90 + 360 - degrees) % 360; }
// dataはonPictureTaken(byte, Camera);で定義 Bitmap origBitmap = BitmapFactory.decodeByteArray( data, 0, data.length); int degrees = getCameraDisplayOrientation(this); // 前述のメソッド int rotatedWidth, rotatedHeight; if (degrees % 180 == 0) { rotatedWidth = origBitmap.getWidth(); rotatedHeight = origBitmap.getHeight(); } else { rotatedWidth = origBitmap.getHeight(); rotatedHeight = origBitmap.getWidth(); } Bitmap rotatedBitmap = Bitmap.createBitmap(rotatedWidth, rotatedHeight, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(rotatedBitmap); canvas.save(); canvas.rotate(degrees, rotatedWidth / 2, rotatedHeight / 2); int offset = (rotatedHeight - rotatedWidth) / 2 * ((degrees - 180) % 180) / 90; canvas.translate(offset, -offset); canvas.drawBitmap(origBitmap, 0, 0, null); canvas.restore(); origBitmap.recycle(); // ここからrotatedBitmapに何か描き足したり
サンプルコード
上記のようにして作った実際のAndroidプロジェクトを以下においています。
Javaの2重チェックイディオムとhappens-before関係
public class AClass { private AHugeClass final value; // 状態を持つ巨大なオブジェクト public AClass() { value = new AHugeClass(); // かなり膨大で副作用のある計算 /* 他の処理 */ } public AHugeClass getValue() { return value; } }
public class AClass { private AHugeClass value; public AClass() { /* 他の処理 */ } public AHugeClass getValue() { if(value == null) value = new AHugeClass(); // かなり膨大で副作用のある計算 return value; } }
public class AClass { private AHugeClass value; public AClass() { /* 他の処理 */ } public synchronized AHugeClass getValue() { if(value == null) value = new AHugeClass(); // かなり膨大で副作用のある計算 return value; } }
public class AClass { private AHugeClass value; public AClass() { /* 他の処理 */ } public AHugeClass getValue() { if(value == null) { synchronized(this) { if(value == null) { value = new AHugeClass(); // かなり膨大で副作用のある計算 } } } return value; } }
メモ:The CERT Oracle Secure Coding Standard for Java
CC-BY-SAのメディアをCCでないWebページで使用してもいいのか
もっと法律的に:第三者の作成した著作物を別のWebページに含めた場合、そのWebページは編集著作物であるか?
もし編集著作物であれば、そのWebページはCC-BY-SAと互換性のあるライセンスを適用しなければならない。
CC-BY-SA を適用できないけどCC-BY-SAの画像を含めたいという状況になったので、いくらか事例がないか調べてみた。
日本語版Wikipediaでは、記事は編集著作物ではなく、テキストとメディアファイルの著作関係は完全に分離できる、という見解を示している。(参考:Wikipedia‐ノート:著作権 - Wikipedia)
しかし、記事によってはメディアファイルと本文の結びつきが強く、その2つを分離できるという考えは正しくないのではないか、という意見もある。(参考:Wikipedia‐ノート:アップロードされたファイルのライセンス/GFDLとCCの衝突の可能性 - Wikipedia)
つまり、CC-BY-SAのメディアをCCでないWebページで使用できるかどうかは、そのWebページとCCのメディアとの結びつきの度合に依存する。その2つがどのくらい結びついていたら駄目なのか、という指標は今のところない、ということらしい。
でも…分離できた方がメディア利用者にとってはいろいろと嬉しいよね。個人的には、Wikipedia程度の画像と記事の結合度なら分離できるという方針でいこう。
TopCoderの各コンテストについて適当な紹介
Copilot Opportunities(共同開発機会)
上記のようにこのコンテストはとても重要なものなので、参加するには以下の条件を満たしている必要がある。
- 過去1年間に3種目以上のコンテスト(SRMとMarathon Matchesは除く)に参加し、
スクリーニングレビューをパスしている - 少なくとも1つの部門で緑色コーダー以上である
- 過去1年間にレビュアーになったことがあり、レビュアー権限を剥奪されていない
- 過去6か月間にコパイロット権限を剥奪されたことがない
Design(設計)
- Studio(スタジオ)
- デザイナー向けのコンテスト。
- ワイヤーフレーム作成やアイコン作成などいろいろな部門があるけど、ここでは詳しく解説しない。
- Conceptualization(概念化)
- Specification(仕様化)
- Architecture(アーキテクチャ)
- Component Design(コンポーネント設計)
Development(開発)
- Component Development(コンポーネント開発)
- 仕様を満たす部品(コンポーネント)を実際に開発するコンテスト。
- 過去2年間のコンテストを見た限り使用する言語は、ほとんどJava、時々.NET、JavaScript、C++、まれにObjectiveC、PHP、PL/SQL、VBAといったところか。
- 実際のコンテストの形式で模擬練習ができるらしいですよ。
- Assembly(組立)
- よくわからない。部品から実際に動くアプリを作るコンテスト? 試作版が完成されているアプリケーションに機能追加するコンテスト?
- とりあえずアセンブリ言語は関係ない。
- 英語の解説でも"Assembly competitions are hard to define."と言ってる…。
- Test Suites(テストスイート)
- Reporting
- 謎。説明がないし今まで一度もコンテストが開かれてない。
UI Development(UI開発)
- UI Prototype(UIプロトタイプ)
- RIA Build(RIA制作)
- RIA(リッチインターネットアプリケーション)のデザインをコードに落とすコンテスト。
- 使用する言語はFlex/Flash/ActionScriptやHTML/CSS/JSがほとんど。ASとJSの両方を書くものも多い。たまにJavaや.NETもある。
- Content Creation(コンテンツ作成)
- コンテンツを作るコンテスト。
- コンテンツは色々。Word・Excel・PowerPointのテンプレートとか。翻訳とか。SRMの歴史解説記事を作ってくれ!っていうのもあった。
QA and Maintenance(品質保証と保守)
- Test Scenarios(テストシナリオ)
- テストケースを作るコンテスト。
- DevelopmentのTest Suitesとほぼ同じコンテストで、開催されるときのプロジェクトの工程が異なる。
- Bug Race
Algorithm(アルゴリズム)
- Single Round Matches(SRM)
- アルゴリズムに関する短時間の定期コンテスト。
- TopCoderのコンテストの中で最も参加者が多い。
- Marathon Match
- アルゴリズムに関する長時間の定期コンテスト。
High School
The Digital Run
ソフトウェア開発コンテストの大まかな流れ
- 登録(Registeration)
- 自分が参加したいコンテストのページへ行き、参加登録をする。
- 参加登録をすると、そのコンテスト専用のフォーラムにアクセスできるようになる。そこで、登録前では得られない追加情報を入手できる。
- 投稿(Submission)
- 作るべきものを作って、投稿する。
- 必要があれば、専用フォーラムで質問をすることもできる。コンテストによっては、専用フォーラムでの対話が作業の中核になるものもある。
- 評価(Review)
- 投稿期間が終わったら、自分の作成物をコンテストのレビュアーに評価・採点してもらう。
- もし自分の評価点が不当に低いと感じたら、専用フォーラムでスコアの修正を要求することができる。最終的なスコアは修正要求を吟味した後に決まる。
- サポート(Support)
- もしコンテストで勝利したら(最も高いスコアを得たら)、このフェーズに入る。
- 一定期間(多くの場合30日間)、自分の制作物で見つかった不具合を修正したり、続く開発工程でのコンテスト参加者からの質問に答えたりする。
- 期限後はバグが見つかっても修正する必要はないが、修正したら追加の報酬金を得られることもある。
その他まとまりのないこと
- ものすごい勢いで色々な作業がマニュアル化されている。すげー
- そのせいか、ソフトウェア開発コンテストがガチガチのウォーターフォールモデルになっていて、LL言語によるプロジェクトがPHP除いて圧倒的に少ない。
- ソフトウェア開発コンテストは、SRMに比べて1コンテスト当たりのサブミッター(コンテスト参加者のうち制作物を投稿した人)が少ない。
- 開発工程のコンテストでは、サブミッターが1人しかいないことも割と頻繁にある。これとかこれとかこれとか。
- Assemblyは半数近くがサブミッター1人な印象
- サブミッター0人も、あるよ。(ただしそのようなコンテストは履歴からは見えない)
- なので、「コンテスト」というよりは「コンテストを利用したアウトソーシング」といった方が正確だと感じた。
- 英語版Wikipediaのページにもそのようなことが書かれている。
- 開発工程のコンテストでは、サブミッターが1人しかいないことも割と頻繁にある。これとかこれとかこれとか。
- フォーラムやサポートでの対話が発生するので、ある程度の英語力は必須だと思う。
- 設計部門のコンテストだとガシガシ文章書かないといけないから、ある程度では済まないだろうけど。
- 開発部門なら、英文書くのはコードのドキュメンテーションと、成果物の変更リスト、フォーラム上の会話くらい。
- 成果物に書くことは部門ごとにテンプレがあるから、それに倣えば深く考えなくてもよさそう。もちろん、テンプレはきっちり読まないといけない。
- フォーラムでの会話は、他のフォーラムの書き込みを参考にすれば大丈夫…か? 参加したことがないので自信がない。
- TopCoder Forums: Getting Started in TopCoder Competitions にあるトピックで自分に関係がありそうなのは読んどくとよさげ
- SRMと比べてとても敷居が高いけど、その分野の知識があるのなら気軽に参加していいと思う。参加費は無料ですし。