強火で進め

このブログではプログラム関連の記事を中心に書いてます。

ChatGPTで数式を解説して貰う方法

Code Interpreterで使えるフォントの情報を見ていたら、数式フォントが含まれていました。 これは数式を数式フォントで記述しながら解説してくれるのでは?と思って検証した所、ちゃんと解説してくれました。

手順

LaTexで式を記述

インターネット上で数式をやりとりするので形式はLaTeX(ラテフ、ラテック)かな?と当たりをつけ、画像からLaTeX形式の文字列に変換してくれるアプリを探す事にしました。

この記事を参考に

gigazine.net

今回はこの「ライプニッツの公式」を使う事にしました。

\sum_{n=0}^{\infty} \frac{(-1)^n}{2 n+1}=\frac{\pi}{4}

自分で式を記述したい場合にはこの様なオンラインツールなども有ります。

Equation Editor for online mathematics - create, integrate and download https://editor.codecogs.com/

手順

ChatGPTで以下の内容を実行します。

この数式の解説をして
\[
\sum_{n=0}^{\infty} \frac{(-1)^n}{2n+1} = \frac{\pi}{4}
\]

一気に全体を理解するのは難しい時はパーツ毎に分けて解説して貰いましょう。

この数式の解説をして
\[
\sum_{n=0}^{\infty} 
\]

こんな感じにお願いすると必ずLaTexでのレンダリングを入れてくれるので分かりやすくなって良いかも?

この数式をLaTexでレンダリングした後に式の解説をして

\sum_{n=0}^{\infty} \frac{(-1)^n}{2 n+1}=\frac{\pi}{4}

Code Interpreterで日本の地図を表示する方法

日本の地図が表示されない

Code Interpreterでは世界地図は表示できますが、日本の地図は表示してくれません。

内容を確認すると「地理情報データ」を渡せば行けそうです。

地理情報データを準備

今回はデータはGADMというサイトのものを使います。 なお、このサイトで配布されているデータは「学術目的、非営利のみOK。再配布禁止」なライセンスなので注意して下さい。
※もし、商用OKなデータを配布しているサイトをご存知の方はコメントに書いて貰えると嬉しいです。

このページShapefileリンクをクリックし、zipファイルをダウンロードします。

zipを展開した後に以下のファイルだけを含めたzipファイルを作成します。

  • gadm36_JPN_1.shp
  • gadm36_JPN_1.shx

Code Interpreterで実行する

Code Interpreterで作成したzipをアップロードし、以下のメッセージ(プロンプト)を入力します。

Pythonで日本の地図を表示して

- アップロードしたファイルをGeopandasで使って

これでこの様に日本の地図が表示されます。

Code Interpreterで日本語を使ったグラフを作る方法

日本語部分が文字化けする

Code Interpreterでグラフを作った場合には日本語部分が文字化けして、俗に豆腐というこの表示→になります。

「これはOpenAI社がバージョンアップしてくれるのを待つしか無いかな?」という状況でした。しかし、この問題を上手い工夫により解決した人達が居ました。

という事で自分でも 試してみました。

試してみた

現在はCode Interpreterは3時間で25メッセージ(プロンプトの事で良いのかな?)までとの制限が有る為、送るメッセージは極力減らしたい所です。

これで行ける

試行錯誤の結果、必要なファイルはzipに固めて以下の様なプロンプトを記述すれば1回のメッセージで作成させる事に成功しました。

test.zipを解凍して以下のルールで棒グラフを描画して下さい。

- データは「data.csv」を使用
- フォントファイルは「NotoSansJP-Medium.ttf」を使用。font nameは「Noto Sans JP Medium」を使用。font familyは「Noto Sans JP Medium」を使用
- グラフのタイトルは「リンゴの販売数」
- グラフのx軸のラベルは「日付」
- グラフのy軸のラベルは「販売数」
- matplotlibで日本語を表示するためには追加の手順が必要な場合が有るとしても作業を進めて下さい。
- 作業中のコメントは日本語で出力

test.zipの中にはグラフ化したいデータのdata.csvとフォントファイルのNotoSansJP-Medium.ttfを入れました。 NotoSansJP-Medium.ttfは文字化けの豆腐をこの世から消し去りたいという想いから作られた無料で使用出来るフォントです。「No豆腐」からNotoという名前が付けられています。 ここからダウンロード出来ます。ダウンロードしたzipファイルには複数のフォントファイルが有るので自分の好きなファイルを使って下さい。

今回使用したdata.csvの内容はこちら。

日付,リンゴの販売数
2023/1/1,68
2023/1/2,65
2023/1/3,39
2023/1/4,133
2023/1/5,84

結果はこの様に日本語部分も正しく描画されました。

解説

Q: なぜ、zipファイル?
A: 一度に1つのファイルしかアップロード出来ない為

Q: 「matplotlibで日本語を表示するためには追加の手順が必要な場合が有るとしても作業を進めて下さい。」
A: ChatGPTから「matplotlibのフォント設定を調整します。ただし、matplotlibで日本語を表示するためには追加の手順が必要な場合があります。この点を承知して進めてよろしいでしょうか?」との質問が返されたため追加

Q: 「作業中のコメントは日本語で出力」
A: 何故か作業中のコメントが英語で出力された事が有ったので

※ChatGPTは同じプロンプトでも結果が異なる事が有るので今回のプロンプトの中から一部の記述が無くても正しく動作する事も有るかと思います。

ちょっと気になった所

以前、アップロードしたファイル

ChatGPTがzipファイルの展開処理を行っている部分の処理内容を表示した所、前にアップロードしたテスト.zipというファイルが残っているのが確認出来ました。この状態になっているという事はもし、「zipファイルを展開して全部の.csvファイルを元にグラフを作って」などと指示をすると以前アップロードしたファイルも処理の対象に含まれ、意図しない結果になりそうな気がします。
※最初はファイル名をテスト.zipと付けて検証していたのですがChatGPTが展開処理をした後に「文字化けしたので日本語ファイル向けの処理をします」と展開処理がもう一度実行されたので英語ファイル名を使う事にしました。

フォントファイルの指定

フォントファイルは「NotoSansJP-Medium.ttf」を使用というプロンプトでは上手く行かなかったのでfont nameは「Noto Sans JP Medium」を使用。font familyは「Noto Sans JP Medium」を使うを追加しました。

他のフォントファイルを使いたい場合にはCode Interpreterでフォントファイルをアップロードした状態で以下のプロンプトを入力するとfont namefont familyを取得出来ます。

このフォントファイルに対して以下の作業をして

- font nameを表示
- font familyを表示
- 作業中のコメントは日本語で出力

Pythonのプログラムが出来る人はfonttoolsモジュールがインストール済みの環境で以下のプログラムを実行すると確認できます。

from fontTools import ttLib

fontPath = 'NotoSansJP-Medium.ttf'
font = ttLib.TTFont(fontPath)
fontFamilyName = font['name'].getDebugName(1)
fullName= font['name'].getDebugName(4)

print("Font Family Name:", fontFamilyName)
print("Font Name:", fullName)

色んなゲームの仕組みをUnityで実装する方法を解説するYouTubeチャンネル「Mix and Jam」

こちらのツイートの動画にて、どんなゲームの仕組みが解説されているか紹介されています。

YouTubeのチャンネルはこちら

【Unity】Collider 2D の Layer Overrides

動作検証環境

  • Unity 2022.2.0f1

はじめに

Rigidbody2D と Box Collider 2D など、 XXX Collider 2D の Inspector に有る Layer Overrides について解説します。

プロパティ

プロパティの説明はこの様になりますがここだけ見てもイマイチ分かりづらいと思いますので次の項目の「解説」と合わせて確認して下さい。

プロパティ名 説明
Layer Override Priority 競合発生時の設定の優先度。
Include Layers 接触が発生するレイヤーを設定。
Exclude Layers 接触が発生しないレイヤーを設定。
Force Send Layers 接触時に力を送るレイヤーを設定。
Force Receive Layers 接触時に力を受けるレイヤーを設定。
Contract Capture Layers キャプチャされるレイヤーを設定。
Callback Layers 他の Collider 2D との衝突時にコールバックを発生されるレイヤーを設定。

解説

A という GameObject に付けられている XXX Collider 2D の Include Layers や Exclude Layers 、それが B という GameObject に付けられている XXX Collider 2D の設定と競合した時の処理のルールはこちら。

  1. A と B の両方が同じルールの場合はそのルールが採用される。
  2. A または B が include (包含) か exclude (除外) を選択している場合はそのルールが採用される。
  3. A と B の両方が include と exclude と異なるルールを選択した場合には Layer Override Priority (プログラムで使う場合は Collider2D.layerOverridePriority )の値が高い方のルールが採用される。
  4. A と B の両方が include と exclude と異なるルールを選択した場合に Layer Override Priority の値が同一の場合には接触は発生しない。

説明用として、以下の様なオブジェクトが配置されているプロジェクトを準備しました。

準備したオブジェクトの色と同じ Layer を準備し、それぞれの色に合わせた Layar を設定しています。

オブジェクト Layer
A Red
B Green
C Blue

Exclude Layers

A の Exclude Layers で Green だけにチェックし、他の Box はデフォルトのままにした場合。

Exclude (除外) に設定した Geen の Layer に属する B には接触しなくなり、存在しないものとして扱われている事が確認できます。床は除外対象では無いので床を透過する事は有りません。

Exclude Layers と Include Layers の組み合わせ

A の Exclude Layers で Green と Blue 、 B の Include (含める) Layers で Red をチェックした場合。

B Include Layers の設定をしているので A と接触しそうに思えますが実際にはルール 4. の「 A と B の両方が include と exclude と異なるルールを選択した場合に Layer Override Priority の値が同一の場合には接触は発生しない。」が適用される為、 B 、 C 共に存在しないものとして扱われます。

追加で B の Layer Override Priority を 1 に変更したい場合。

B との接触が発生する様になりました。これはルール 3. の「 A と B の両方が include と exclude と異なるルールを選択した場合には Layer Override Priority (プログラムで使う場合は Collider2D.layerOverridePriority )の値が高い方のルールが採用される。」が適用された為です。

Force Send Layers

A の Force Send Layers で Green だけにチェックし、他の Box はデフォルトのままにした場合。

A の力( Force )は B だけに送られる( Send) ので移動しますが、 C には力が送られないので移動しない事が確認できます。

Force Receive Layers

A の Force Receive Layers で Green と「床」のレイヤーで有る Defualt だけにチェックし、他の Box はデフォルトのままにした場合。

A は先に落ちた C からの力は受けない(移動しない)。しかし、その後の B の力は受ける為、移動する事が確認できます。

Contract Capture Layers

Contract Capture (キャプチャ契約) Layers は以下の様な API の動作に影響を与えます。チェックが付いてないレイヤーはキャプチャの対象外となり、「接触している」と判定されなくなったり、 OnCollisionEnter2D などのコールバックが呼ばれなくなります。

  • Physics2D.IsTouching
  • Rigidbody2D.IsTouching
  • Collider2D.IsTouching,
  • Physics2D.IsTouchingLayers
  • Rigidbody2D.IsTouchingLayers
  • Collider2D.IsTouchingLayers
  • Physics2D.GetContacts
  • Rigidbody2D.GetContacts
  • Collider2D.GetContacts
  • OnCollisionEnter2D
  • OnCollisionStay2D
  • OnCollisionExit2D
  • OnTriggerEnter2D
  • OnTriggerStay2D
  • OnTriggerExit2D

docs.unity3d.com

Callback Layers

Callback Layers でチェックが付いているレイヤーに属する GameObject の Collider 2D との衝突時にはコールバックを発生させます。 ここの設定に影響を受けるものは以下のものです。

  • OnCollisionEnter2D
  • OnCollisionStay2D
  • OnCollisionExit2D
  • OnTriggerEnter2D
  • OnTriggerStay2D
  • OnTriggerExit2D

docs.unity3d.com

【Unity】 Platform Effector 2D

動作検証環境

  • Unity 2022.2.0f1

はじめに

Platform Effector 2D は2Dゲームの床を作る時に使うコンポーネントです。

docs.unity3d.com

プロパティ

プロパティ名 説明
Use Collider Mask Collider Mask を使いたい時にチェック。
Collider Mask ここでチェックを付けた Layer に対してのみ Platform Effector 2D の処理対象となる。
Use One Way チェックした時、一方通行の設定が有効。
Use One Way Grouping チェックした時、複数の Collider が使われている時に全ての Collider が一方通行を通過した時のみ地面に着地する。チェックされてない時は通過した Collider のみが地面に着地する。
Surface Arc Use One Way がチェックしされている時のみ有効。地面の範囲を角度で指定。
Use Side Friction チェックした時、横から当たった時に Friction (摩擦)が考慮されます。
Use Side Bounce チェックした時、横から当たった時に Bounce (跳ね返り)が考慮されます。
Side Arc 衝突が発生した時に側面とみなす角度を設定。側面と判定された時には Use Side Friction と Use Side Bounce の設定が反映されます。

解説

Use One Way Grouping

この様なサンプルを準備します。

こういう構成になっていて、

こういう Component を設定しています。

■ Use One Way Grouping にチェックしない時

通過した赤いBoxだけが地面に立ちます。

■ Use One Way Grouping にチェックした時

両方が通過しない場合には地面に立たずに落下します。

Surface Arc

Scene ビュー上には角度が可視化されています。

指定した角度の範囲に衝突法線( collision normal )が収まった場合、地面とみなされます。

Circle Collider 2D と一緒に使った時

Surface Arc の範囲から外れたら落下しているのが確認できます。

Polygon Collider 2D と一緒に使った時

最初は Surface Arc = 30 、途中から Surface Arc = 140 に変更しています。

30 の時は壁を通過しますが 140 になったら壁に衝突し始めるのが確認できます。

なお、 Surface Arc の円弧の範囲が壁際で分かりやすい様に自作のデバッグ描画を行っています。

因みにコードはこちらになります。

using UnityEngine;

public class DebugSurfaceArc : MonoBehaviour
{
    [SerializeField] PlatformEffector2D platform;
    float arc = 0;
    [SerializeField] float scale = 1.0f;

    private Transform trans;
    // Start is called before the first frame update

    private void Start()
    {
        trans = gameObject.transform;
        if (platform == null)
        {
            Debug.LogError("PlatformEffector2Dの参照を設定して下さい。");
        }
    }
    void OnDrawGizmos()
    {
        if (trans == null) return;
        if (platform != null)
        {
            arc = platform.surfaceArc;
        }

        float halfArc = arc * 0.5f;
        float arc1 = 90.0f + halfArc;
        float arc2 = 90.0f - halfArc;
        Vector3 startPoint = trans.position;
        float rad;

        Vector3 normal = Vector3.up;

        // Arcの範囲
        {
            Vector3 direction;

            Gizmos.color = Color.white;
            // 円弧描画のAPIが無いので DrawWireSphere で代用
            Gizmos.DrawWireSphere(startPoint, scale);

            Gizmos.color = Color.green;
            startPoint = trans.position;
            // 度(°)をラジアンに変換
            rad = Mathf.PI / 180 * arc1;
            direction = Vector3.zero;
            direction.x = Mathf.Cos(rad);
            direction.y = Mathf.Sin(rad);
            direction *= scale;
            Gizmos.DrawRay(startPoint, direction);
            rad = Mathf.PI / 180 * arc2;
            direction = Vector3.zero;
            direction.x = Mathf.Cos(rad);
            direction.y = Mathf.Sin(rad);
            direction *= scale;
            Gizmos.DrawRay(startPoint, direction);
        }

        // Surface面と法線との直角を表す
        {
            float lineSize = 0.2f * scale;
            Vector3 p1, p2, p3;

            startPoint = trans.position;
            p1 = startPoint;
            p1.x += lineSize;
            p2 = p1;
            p2.y += lineSize;
            p3 = p2;
            p3.x -= lineSize;
            Gizmos.color = Color.yellow;
            Gizmos.DrawLine(startPoint, p1);
            Gizmos.DrawLine(p1, p2);
            Gizmos.DrawLine(p2, p3);
        }

        // 法線
        Gizmos.color = Color.red;
        Gizmos.DrawRay(startPoint, normal * scale);
    }
}

移動している円の顔が衝突する壁の法線は緑の矢印で示した向きとなります。

これは Surface Arc = 140 まで増やすと範囲内に収まる事が確認できます。その為、 140 に変わった時点から壁に衝突する様になりました。

Box Collider 2D と一緒に使った時

Box Collider 2D と一緒に使った時にはこのくらい小さい範囲でも衝突が発生します。 Surface Arc = 1 でも衝突が発生し、 0 にすると流石に通過する様になります。

円の顔が地面にぶつかる時の衝突法線は緑の矢印の向きとなります。これは Surface Arc の範囲内となるので衝突するという挙動になります。

Use Side Friction と Use Side Bounce

■ Use Side Friction 、 Use Side Bounce のどちらにもチェックをしていない時

■ Use Side Friction をチェックした時

摩擦が効いているので回転が発生しているのが確認できます。

■ Use Side Bounce をチェックした時

跳ねるようになったのが確認できます。

【Unity】 Surface Effector 2D

動作検証環境

  • Unity 2022.2.0f1

はじめに

Surface Effector 2D はエスカレーターやベルトコンベアな様なものを再現する事ができるコンポーネントです。

docs.unity3d.com

プロパティ

プロパティ名 説明
Use Collider Mask Collider Mask を使いたい時にチェック。
Collider Mask ここでチェックを付けた Layer に対してのみ Surface Effector 2D の処理対象となる。
Speed 接地したターゲットに加えられる速度。正の数の場合には X 方向(右方向)、負の数の場合には -X 方向(左方向)の力が加えられる。
Speed Variation ランダムで設定される速度。「Speed+(0~ここで指定した値のランダム値)」が最終的に出力される速度になる。
Force Scale 指定された速度に到達しようとする力をスケーリングを0~1.0の範囲で指定。0の場合は全く力が加えられなくなり、 Surface Effector 2D を無効化した状態と同様になる。1にした場合にはターゲットの現在の Velocity を無視して指定した速度( Speed で指定した値)を強制します。
Use Contact Force チェックをすると接触した時にターゲットに回転の力が加わります。
Use Friction チェックをすると Friction (摩擦)が考慮されます。
Use Bounce チェックをすると Bounce (跳ね返り)が考慮されます。

解説

Speed と Speed Variation

Speed と Speed Variation の値をこの様にした場合に移動速度がバラけているのが確認できます。

Force Scale

円形の顔は右方向の力を常に発生していて、床からは左方向への速度を発生を受けるというサンプルを準備しました。

■ Force Scale = 0.01

床からの力を突破して右へ移動しました。

■ Force Scale = 0.1

床からの力が勝ち、左へ移動しました。