x=0から X=>0で 山が高きなるサインカーブ
t(y) の 振幅方向が 逆だと思う x=0から
x>0で 山が高くなってるのに

あってるわけか
bl_info = {
    "name": "Sine Wave Generator (Space & Time Trajectory)",
    "author": "ChatGPT",
    "version": (2, 2, 0),
    "blender": (5, 0, 0),
    "location": "View3D > Sidebar (N Panel)",
    "description": "進行波、時間軌跡、t=ax波面などをリアルタイムで描画します。",
    "category": "3D View",
}

import bpy
import math

# ===================================
# 共通定義 & 初期設定
# ===================================
ADDON_TITLE = "Sine Wave Generator"
PREFIX = "sine_wave"
OBJ_PREFIX = "SINE_WAVE_"

SINE_AMPLITUDE_DEFAULT = 2.0
SINE_FREQUENCY_DEFAULT = 1.0
SINE_LENGTH_DEFAULT = 10.0
SINE_TIME_MAX_DEFAULT = 10.0
SINE_TIME_DEFAULT = 1.0
SINE_DELAY_DEFAULT = 0.0
SINE_RESOLUTION_DEFAULT = 128
SINE_WAVE_SPEED_X_DEFAULT = 1.0

SINE_LOC_X_DEFAULT = 0.0
SINE_LOC_Y_DEFAULT = 0.0
SINE_LOC_Z_DEFAULT = 0.0

INIT_COLOR = (0.5, 0.5, 0.5, 0.8)
MAIN_COLOR = (0.2, 0.6, 1.0, 1.0)
TRAJ_COLOR = (1.0, 0.8, 0.2, 1.0)
TX_COLOR   = (0.2, 1.0, 0.5, 1.0)

# ===================================
# データクリーンアップ関数
# ===================================
def clear_sine_wave_data():
    """このアドオンで生成したオブジェクト、カーブ、マテリアルを全て削除"""
    for obj in list(bpy.data.objects):
        if obj.name.startswith(OBJ_PREFIX):
            bpy.data.objects.remove(obj, do_unlink=True)
    for crv in list(bpy.data.curves):
        if crv.name.startswith(OBJ_PREFIX):
            bpy.data.curves.remove(crv)
    for mat in list(bpy.data.materials):
        if mat.name.startswith(OBJ_PREFIX):
            bpy.data.materials.remove(mat)

# ===================================
# 共通の変位計算 & 波形生成ロジック
# ===================================
def calculate_z_displacement(x, t, props):
    phase_x = x - props.wave_speed_x * (t - props.delay)
    return props.amplitude * math.sin(props.frequency * phase_x) + SINE_LOC_Z_DEFAULT

def create_curve_object(name, thickness, color, collection):
    curve_data = bpy.data.curves.new(name=name, type='CURVE')
    curve_data.dimensions = '3D'
    curve_data.bevel_depth = thickness
    curve_data.bevel_resolution = 4
    
    spline = curve_data.splines.new(type='POLY')
    obj = bpy.data.objects.new(name, curve_data)
    collection.objects.link(obj)
    
    mat = bpy.data.materials.new(name=f"{name}_Mat")
    mat.use_nodes = True
    mat.blend_method = 'BLEND'
    bsdf = mat.node_tree.nodes.get("Principled BSDF")
    if bsdf:
        bsdf.inputs['Base Color'].default_value = color
        if len(color) == 4 and color[3] < 1.0:
            bsdf.inputs['Alpha'].default_value = color[3]
    obj.data.materials.append(mat)
    return spline

def generate_waves(context):
    props = context.scene.sine_wave_props
    
    clear_sine_wave_data()
    
    coll_name = "SineWave_Collection"
    if coll_name in bpy.data.collections:
        coll = bpy.data.collections[coll_name]
    else:
        coll = bpy.data.collections.new(coll_name)
        context.scene.collection.children.link(coll)

    # 1. 初期波形 (t=0)
    if props.init_show:
        spline_init = create_curve_object(f"{OBJ_PREFIX}Init_t0", props.init_thickness, props.init_color, coll)
        spline_init.points.add(props.resolution - 1)
        for i in range(props.resolution):
            x_local = (i / (props.resolution - 1)) * props.length
            y = 0.0 + SINE_LOC_Y_DEFAULT
            z = calculate_z_displacement(x_local, 0.0, props)
            spline_init.points[i].co = (x_local + SINE_LOC_X_DEFAULT, y, z, 1.0)

    # 2. メインの波 (現在の時間)
    if props.main_show:
        spline_main = create_curve_object(f"{OBJ_PREFIX}Main", props.thickness, props.color_main, coll)
        spline_main.points.add(props.resolution - 1)
        for i in range(props.resolution):
            x_local = (i / (props.resolution - 1)) * props.length
            y = props.time_t + SINE_LOC_Y_DEFAULT
            z = calculate_z_displacement(x_local, props.time_t, props)
            spline_main.points[i].co = (x_local + SINE_LOC_X_DEFAULT, y, z, 1.0)

    # 3. 時間軌跡 (x=0)
    if props.traj_show and props.time_max > 0.0:
        spline_traj = create_curve_object(f"{OBJ_PREFIX}Trajectory", props.traj_thickness, props.traj_color, coll)
        spline_traj.points.add(props.resolution - 1)
        for i in range(props.resolution):
            tau = (i / (props.resolution - 1)) * props.time_max
            x_local = 0.0
            y = tau + SINE_LOC_Y_DEFAULT
            z = calculate_z_displacement(x_local, tau, props)
            spline_traj.points[i].co = (x_local + SINE_LOC_X_DEFAULT, y, z, 1.0)

    # 4. t=ax 波面
    if props.tx_show:
        spline_tx = create_curve_object(f"{OBJ_PREFIX}Wave_tx", props.tx_thickness, props.tx_color, coll)
        spline_tx.points.add(props.resolution - 1)
        for i in range(props.resolution):
            # ======== 変更点: ゼロ除算の回避 ========
            if props.tx_slope_a == 0.0:
                max_tx_length = props.length
            else:
                max_tx_length = min(props.length, props.time_max / props.tx_slope_a)
            # ========================================

            x_local = (i / (props.resolution - 1)) * max_tx_length
            t_local = props.tx_slope_a * x_local
            y = t_local + SINE_LOC_Y_DEFAULT
            z = calculate_z_displacement(x_local, t_local, props)
            spline_tx.points[i].co = (x_local + SINE_LOC_X_DEFAULT, y, z, 1.0)

# ===================================
# リアルタイム反映のコールバック
# ===================================
def update_waves_cb(self, context):
    if context and hasattr(context.scene, 'sine_wave_props'):
        generate_waves(context)

# ===================================
# プロパティ定義
# ===================================
class SineWaveProperties(bpy.types.PropertyGroup):
    amplitude: bpy.props.FloatProperty(name="振幅高さ (Z軸)", default=SINE_AMPLITUDE_DEFAULT, update=update_waves_cb)
    frequency: bpy.props.FloatProperty(name="周波数 (k)", default=SINE_FREQUENCY_DEFAULT, update=update_waves_cb)
    
    length: bpy.props.FloatProperty(name="空間の長さ (X最大)", default=SINE_LENGTH_DEFAULT, update=update_waves_cb)
    time_max: bpy.props.FloatProperty(name="時間の長さ (Y最大)", default=SINE_TIME_MAX_DEFAULT, update=update_waves_cb)
    
    time_t: bpy.props.FloatProperty(
        name="現在の時間 t", 
        default=SINE_TIME_DEFAULT, 
        soft_min=0.0, 
        soft_max=10.0, 
        update=update_waves_cb
    )
    
    wave_speed_x: bpy.props.FloatProperty(name="X方向速度 (v)", default=SINE_WAVE_SPEED_X_DEFAULT, soft_min=-10.0, soft_max=10.0, update=update_waves_cb)
    delay: bpy.props.FloatProperty(name="開始時間の遅れ", default=SINE_DELAY_DEFAULT, update=update_waves_cb)
    resolution: bpy.props.IntProperty(name="解像度", default=SINE_RESOLUTION_DEFAULT, min=2, update=update_waves_cb)
    
    init_show: bpy.props.BoolProperty(name="初期波 (t=0)", default=True, update=update_waves_cb)
    init_thickness: bpy.props.FloatProperty(name="初期波の太さ", default=0.05, min=0.0, update=update_waves_cb)
    init_color: bpy.props.FloatVectorProperty(name="初期波の色", subtype='COLOR', size=4, default=INIT_COLOR, min=0.0, max=1.0, update=update_waves_cb)

    main_show: bpy.props.BoolProperty(name="時間波形 (t=t)", default=True, update=update_waves_cb)
    thickness: bpy.props.FloatProperty(name="時間波形の太さ", default=0.15, min=0.0, update=update_waves_cb)
    color_main: bpy.props.FloatVectorProperty(name="時間波形の色", subtype='COLOR', size=4, default=MAIN_COLOR, min=0.0, max=1.0, update=update_waves_cb)
    
    traj_show: bpy.props.BoolProperty(name="時間軌跡 (x=0)", default=True, update=update_waves_cb)
    traj_thickness: bpy.props.FloatProperty(name="軌跡の太さ", default=0.1, min=0.0, update=update_waves_cb)
    traj_color: bpy.props.FloatVectorProperty(name="軌跡の色", subtype='COLOR', size=4, default=TRAJ_COLOR, min=0.0, max=1.0, update=update_waves_cb)

    tx_show: bpy.props.BoolProperty(name="t=ax 波面", default=True, update=update_waves_cb)
    # ======== 変更点: min=0.0 に変更 ========
    tx_slope_a: bpy.props.FloatProperty(name="係数 (a)", default=1.0, min=0.0, max=1.0, update=update_waves_cb)
    # ========================================
    tx_thickness: bpy.props.FloatProperty(name="t=ax 波の太さ", default=0.12, min=0.0, update=update_waves_cb)
    tx_color: bpy.props.FloatVectorProperty(name="t=ax 波の色", subtype='COLOR', size=4, default=TX_COLOR, min=0.0, max=1.0, update=update_waves_cb)

# ===================================
# UI パネル
# ===================================
class SINE_WAVE_PT_panel(bpy.types.Panel):
    bl_label = ADDON_TITLE
    bl_idname = f"{PREFIX}_PT_panel"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = "SineWave"

    def draw(self, context):
        layout = self.layout
        props = context.scene.sine_wave_props

        # 1. 基本設定
        box = layout.box()
        box.label(text="物理パラメータ", icon='VIEW_ORTHO')
        box.prop(props, "amplitude")
        box.prop(props, "frequency")
        box.prop(props, "length")
        box.prop(props, "time_max")
        
        box.separator()
        box.prop(props, "time_t", slider=True)
        box.prop(props, "wave_speed_x")
        box.prop(props, "delay")
        box.prop(props, "resolution")
        
        # 2. 波の表示・非表示 トグルボタン群
        box2 = layout.box()
        box2.label(text="波の表示切り替え (ON/OFF)", icon='RESTRICT_VIEW_OFF')
        row = box2.row(align=True)
        row.prop(props, "init_show", toggle=True, text="t=0")
        row.prop(props, "main_show", toggle=True, text="t=t")
        row.prop(props, "traj_show", toggle=True, text="x=0")
        row.prop(props, "tx_show", toggle=True, text="t=ax")

        # 3. 見た目の詳細設定
        box3 = layout.box()
        box3.label(text="色と太さの設定", icon='MATERIAL')
        
        if props.init_show:
            row = box3.row()
            row.label(text="初期 (t=0):")
            row.prop(props, "init_thickness", text="太さ")
            row.prop(props, "init_color", text="")

        if props.main_show:
            row = box3.row()
            row.label(text=f"現在 (t={props.time_t:.1f}):")
            row.prop(props, "thickness", text="太さ")
            row.prop(props, "color_main", text="")
            
        if props.traj_show:
            row = box3.row()
            row.label(text="軌跡 (x=0):")
            row.prop(props, "traj_thickness", text="太さ")
            row.prop(props, "traj_color", text="")

        if props.tx_show:
            box3.separator()
            row_a = box3.row()
            row_a.label(text="波面 (t=ax):")
            row_a.prop(props, "tx_slope_a", text="係数 a", slider=True)
            
            row = box3.row()
            row.label(text="") # 余白用
            row.prop(props, "tx_thickness", text="太さ")
            row.prop(props, "tx_color", text="")

# ===================================
# 登録処理
# ===================================
def setup_viewport_ui():
    for window in bpy.context.window_manager.windows:
        for area in window.screen.areas:
            if area.type == 'VIEW_3D':
                for space in area.spaces:
                    if space.type == 'VIEW_3D':
                        space.shading.type = 'MATERIAL'
                        space.show_region_ui = True
    
    if bpy.context.scene:
        generate_waves(bpy.context)
    return None

classes = (SineWaveProperties, SINE_WAVE_PT_panel)

def register():
    for cls in classes:
        bpy.utils.register_class(cls)
    bpy.types.Scene.sine_wave_props = bpy.props.PointerProperty(type=SineWaveProperties)
    
    bpy.app.timers.register(setup_viewport_ui, first_interval=0.1)

def unregister():
    for cls in reversed(classes):
        bpy.utils.unregister_class(cls)
    del bpy.types.Scene.sine_wave_props
    
    clear_sine_wave_data()

if __name__ == "__main__":
    register()
振動数を t(y)の1単位時間あたりにして
bl_info = {
    "name": "Sine Wave Generator (Space & Time Trajectory)",
    "author": "ChatGPT",
    "version": (2, 2, 0),
    "blender": (5, 0, 0),
    "location": "View3D > Sidebar (N Panel)",
    "description": "進行波、時間軌跡、t=ax波面などをリアルタイムで描画します。",
    "category": "3D View",
}

import bpy
import math

# ===================================
# 共通定義 & 初期設定
# ===================================
ADDON_TITLE = "Sine Wave Generator"
PREFIX = "sine_wave"
OBJ_PREFIX = "SINE_WAVE_"

SINE_AMPLITUDE_DEFAULT = 2.0
SINE_FREQUENCY_DEFAULT = 1.0
SINE_LENGTH_DEFAULT = 10.0
SINE_TIME_MAX_DEFAULT = 10.0
SINE_TIME_DEFAULT = 1.0
SINE_DELAY_DEFAULT = 0.0
SINE_RESOLUTION_DEFAULT = 128
SINE_WAVE_SPEED_X_DEFAULT = 1.0

SINE_LOC_X_DEFAULT = 0.0
SINE_LOC_Y_DEFAULT = 0.0
SINE_LOC_Z_DEFAULT = 0.0

INIT_COLOR = (0.5, 0.5, 0.5, 0.8)
MAIN_COLOR = (0.2, 0.6, 1.0, 1.0)
TRAJ_COLOR = (1.0, 0.8, 0.2, 1.0)
TX_COLOR   = (0.2, 1.0, 0.5, 1.0)

# ===================================
# データクリーンアップ関数
# ===================================
def clear_sine_wave_data():
    """このアドオンで生成したオブジェクト、カーブ、マテリアルを全て削除"""
    for obj in list(bpy.data.objects):
        if obj.name.startswith(OBJ_PREFIX):
            bpy.data.objects.remove(obj, do_unlink=True)
    for crv in list(bpy.data.curves):
        if crv.name.startswith(OBJ_PREFIX):
            bpy.data.curves.remove(crv)
    for mat in list(bpy.data.materials):
        if mat.name.startswith(OBJ_PREFIX):
            bpy.data.materials.remove(mat)

# ===================================
# 共通の変位計算 & 波形生成ロジック
# ===================================
def calculate_z_displacement(x, t, props):
    phase_x = x - props.wave_speed_x * (t - props.delay)
    return props.amplitude * math.sin(props.frequency * phase_x) + SINE_LOC_Z_DEFAULT

def create_curve_object(name, thickness, color, collection):
    curve_data = bpy.data.curves.new(name=name, type='CURVE')
    curve_data.dimensions = '3D'
    curve_data.bevel_depth = thickness
    curve_data.bevel_resolution = 4
    
    spline = curve_data.splines.new(type='POLY')
    obj = bpy.data.objects.new(name, curve_data)
    collection.objects.link(obj)
    
    mat = bpy.data.materials.new(name=f"{name}_Mat")
    mat.use_nodes = True
    mat.blend_method = 'BLEND'
    bsdf = mat.node_tree.nodes.get("Principled BSDF")
    if bsdf:
        bsdf.inputs['Base Color'].default_value = color
        if len(color) == 4 and color[3] < 1.0:
            bsdf.inputs['Alpha'].default_value = color[3]
    obj.data.materials.append(mat)
    return spline

def generate_waves(context):
    props = context.scene.sine_wave_props
    
    clear_sine_wave_data()
    
    coll_name = "SineWave_Collection"
    if coll_name in bpy.data.collections:
        coll = bpy.data.collections[coll_name]
    else:
        coll = bpy.data.collections.new(coll_name)
        context.scene.collection.children.link(coll)

    # 1. 初期波形 (t=0)
    if props.init_show:
        spline_init = create_curve_object(f"{OBJ_PREFIX}Init_t0", props.init_thickness, props.init_color, coll)
        spline_init.points.add(props.resolution - 1)
        for i in range(props.resolution):
            x_local = (i / (props.resolution - 1)) * props.length
            y = 0.0 + SINE_LOC_Y_DEFAULT
            z = calculate_z_displacement(x_local, 0.0, props)
            spline_init.points[i].co = (x_local + SINE_LOC_X_DEFAULT, y, z, 1.0)

    # 2. メインの波 (現在の時間)
    if props.main_show:
        spline_main = create_curve_object(f"{OBJ_PREFIX}Main", props.thickness, props.color_main, coll)
        spline_main.points.add(props.resolution - 1)
        for i in range(props.resolution):
            x_local = (i / (props.resolution - 1)) * props.length
            y = props.time_t + SINE_LOC_Y_DEFAULT
            z = calculate_z_displacement(x_local, props.time_t, props)
            spline_main.points[i].co = (x_local + SINE_LOC_X_DEFAULT, y, z, 1.0)

    # 3. 時間軌跡 (x=0)
    if props.traj_show and props.time_max > 0.0:
        spline_traj = create_curve_object(f"{OBJ_PREFIX}Trajectory", props.traj_thickness, props.traj_color, coll)
        spline_traj.points.add(props.resolution - 1)
        for i in range(props.resolution):
            tau = (i / (props.resolution - 1)) * props.time_max
            x_local = 0.0
            y = tau + SINE_LOC_Y_DEFAULT
            z = calculate_z_displacement(x_local, tau, props)
            spline_traj.points[i].co = (x_local + SINE_LOC_X_DEFAULT, y, z, 1.0)

    # 4. t=ax 波面
    if props.tx_show:
        spline_tx = create_curve_object(f"{OBJ_PREFIX}Wave_tx", props.tx_thickness, props.tx_color, coll)
        spline_tx.points.add(props.resolution - 1)
        for i in range(props.resolution):
            # ======== 変更点: ゼロ除算の回避 ========
            if props.tx_slope_a == 0.0:
                max_tx_length = props.length
            else:
                max_tx_length = min(props.length, props.time_max / props.tx_slope_a)
            # ========================================

            x_local = (i / (props.resolution - 1)) * max_tx_length
            t_local = props.tx_slope_a * x_local
            y = t_local + SINE_LOC_Y_DEFAULT
            z = calculate_z_displacement(x_local, t_local, props)
            spline_tx.points[i].co = (x_local + SINE_LOC_X_DEFAULT, y, z, 1.0)

# ===================================
# リアルタイム反映のコールバック
# ===================================
def update_waves_cb(self, context):
    if context and hasattr(context.scene, 'sine_wave_props'):
        generate_waves(context)

# ===================================
# プロパティ定義
# ===================================
class SineWaveProperties(bpy.types.PropertyGroup):
    amplitude: bpy.props.FloatProperty(name="振幅高さ (Z軸)", default=SINE_AMPLITUDE_DEFAULT, update=update_waves_cb)
    frequency: bpy.props.FloatProperty(name="周波数 (k)", default=SINE_FREQUENCY_DEFAULT, update=update_waves_cb)
    
    length: bpy.props.FloatProperty(name="空間の長さ (X最大)", default=SINE_LENGTH_DEFAULT, update=update_waves_cb)
    time_max: bpy.props.FloatProperty(name="時間の長さ (Y最大)", default=SINE_TIME_MAX_DEFAULT, update=update_waves_cb)
    
    time_t: bpy.props.FloatProperty(
        name="現在の時間 t", 
        default=SINE_TIME_DEFAULT, 
        soft_min=0.0, 
        soft_max=10.0, 
        update=update_waves_cb
    )
    
    wave_speed_x: bpy.props.FloatProperty(name="X方向速度 (v)", default=SINE_WAVE_SPEED_X_DEFAULT, soft_min=-10.0, soft_max=10.0, update=update_waves_cb)
    delay: bpy.props.FloatProperty(name="開始時間の遅れ", default=SINE_DELAY_DEFAULT, update=update_waves_cb)
    resolution: bpy.props.IntProperty(name="解像度", default=SINE_RESOLUTION_DEFAULT, min=2, update=update_waves_cb)
    
    init_show: bpy.props.BoolProperty(name="初期波 (t=0)", default=True, update=update_waves_cb)
    init_thickness: bpy.props.FloatProperty(name="初期波の太さ", default=0.05, min=0.0, update=update_waves_cb)
    init_color: bpy.props.FloatVectorProperty(name="初期波の色", subtype='COLOR', size=4, default=INIT_COLOR, min=0.0, max=1.0, update=update_waves_cb)

    main_show: bpy.props.BoolProperty(name="時間波形 (t=t)", default=True, update=update_waves_cb)
    thickness: bpy.props.FloatProperty(name="時間波形の太さ", default=0.15, min=0.0, update=update_waves_cb)
    color_main: bpy.props.FloatVectorProperty(name="時間波形の色", subtype='COLOR', size=4, default=MAIN_COLOR, min=0.0, max=1.0, update=update_waves_cb)
    
    traj_show: bpy.props.BoolProperty(name="時間軌跡 (x=0)", default=True, update=update_waves_cb)
    traj_thickness: bpy.props.FloatProperty(name="軌跡の太さ", default=0.1, min=0.0, update=update_waves_cb)
    traj_color: bpy.props.FloatVectorProperty(name="軌跡の色", subtype='COLOR', size=4, default=TRAJ_COLOR, min=0.0, max=1.0, update=update_waves_cb)

    tx_show: bpy.props.BoolProperty(name="t=ax 波面", default=True, update=update_waves_cb)
    # ======== 変更点: min=0.0 に変更 ========
    tx_slope_a: bpy.props.FloatProperty(name="係数 (a)", default=1.0, min=0.0, max=1.0, update=update_waves_cb)
    # ========================================
    tx_thickness: bpy.props.FloatProperty(name="t=ax 波の太さ", default=0.12, min=0.0, update=update_waves_cb)
    tx_color: bpy.props.FloatVectorProperty(name="t=ax 波の色", subtype='COLOR', size=4, default=TX_COLOR, min=0.0, max=1.0, update=update_waves_cb)

# ===================================
# UI パネル
# ===================================
class SINE_WAVE_PT_panel(bpy.types.Panel):
    bl_label = ADDON_TITLE
    bl_idname = f"{PREFIX}_PT_panel"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = "SineWave"

    def draw(self, context):
        layout = self.layout
        props = context.scene.sine_wave_props

        # 1. 基本設定
        box = layout.box()
        box.label(text="物理パラメータ", icon='VIEW_ORTHO')
        box.prop(props, "amplitude")
        box.prop(props, "frequency")
        box.prop(props, "length")
        box.prop(props, "time_max")
        
        box.separator()
        box.prop(props, "time_t", slider=True)
        box.prop(props, "wave_speed_x")
        box.prop(props, "delay")
        box.prop(props, "resolution")
        
        # 2. 波の表示・非表示 トグルボタン群
        box2 = layout.box()
        box2.label(text="波の表示切り替え (ON/OFF)", icon='RESTRICT_VIEW_OFF')
        row = box2.row(align=True)
        row.prop(props, "init_show", toggle=True, text="t=0")
        row.prop(props, "main_show", toggle=True, text="t=t")
        row.prop(props, "traj_show", toggle=True, text="x=0")
        row.prop(props, "tx_show", toggle=True, text="t=ax")

        # 3. 見た目の詳細設定
        box3 = layout.box()
        box3.label(text="色と太さの設定", icon='MATERIAL')
        
        if props.init_show:
            row = box3.row()
            row.label(text="初期 (t=0):")
            row.prop(props, "init_thickness", text="太さ")
            row.prop(props, "init_color", text="")

        if props.main_show:
            row = box3.row()
            row.label(text=f"現在 (t={props.time_t:.1f}):")
            row.prop(props, "thickness", text="太さ")
            row.prop(props, "color_main", text="")
            
        if props.traj_show:
            row = box3.row()
            row.label(text="軌跡 (x=0):")
            row.prop(props, "traj_thickness", text="太さ")
            row.prop(props, "traj_color", text="")

        if props.tx_show:
            box3.separator()
            row_a = box3.row()
            row_a.label(text="波面 (t=ax):")
            row_a.prop(props, "tx_slope_a", text="係数 a", slider=True)
            
            row = box3.row()
            row.label(text="") # 余白用
            row.prop(props, "tx_thickness", text="太さ")
            row.prop(props, "tx_color", text="")

# ===================================
# 登録処理
# ===================================
def setup_viewport_ui():
    for window in bpy.context.window_manager.windows:
        for area in window.screen.areas:
            if area.type == 'VIEW_3D':
                for space in area.spaces:
                    if space.type == 'VIEW_3D':
                        space.shading.type = 'MATERIAL'
                        space.show_region_ui = True
    
    if bpy.context.scene:
        generate_waves(bpy.context)
    return None

classes = (SineWaveProperties, SINE_WAVE_PT_panel)

def register():
    for cls in classes:
        bpy.utils.register_class(cls)
    bpy.types.Scene.sine_wave_props = bpy.props.PointerProperty(type=SineWaveProperties)
    
    bpy.app.timers.register(setup_viewport_ui, first_interval=0.1)

def unregister():
    for cls in reversed(classes):
        bpy.utils.unregister_class(cls)
    del bpy.types.Scene.sine_wave_props
    
    clear_sine_wave_data()

if __name__ == "__main__":
    register()
t=ax係数 0から1にして
bl_info = {
    "name": "Sine Wave Generator (Space & Time Trajectory)",
    "author": "ChatGPT",
    "version": (2, 1, 0),
    "blender": (5, 0, 0),
    "location": "View3D > Sidebar (N Panel)",
    "description": "進行波、時間軌跡、t=ax波面などをリアルタイムで描画します。",
    "category": "3D View",
}

import bpy
import math

# ===================================
# 共通定義 & 初期設定
# ===================================
ADDON_TITLE = "Sine Wave Generator"
PREFIX = "sine_wave"
OBJ_PREFIX = "SINE_WAVE_"

SINE_AMPLITUDE_DEFAULT = 2.0
SINE_FREQUENCY_DEFAULT = 1.0
SINE_LENGTH_DEFAULT = 10.0
SINE_TIME_MAX_DEFAULT = 10.0
SINE_TIME_DEFAULT = 1.0
SINE_DELAY_DEFAULT = 0.0
SINE_RESOLUTION_DEFAULT = 128
SINE_WAVE_SPEED_X_DEFAULT = 1.0

SINE_LOC_X_DEFAULT = 0.0
SINE_LOC_Y_DEFAULT = 0.0
SINE_LOC_Z_DEFAULT = 0.0

INIT_COLOR = (0.5, 0.5, 0.5, 0.8)
MAIN_COLOR = (0.2, 0.6, 1.0, 1.0)
TRAJ_COLOR = (1.0, 0.8, 0.2, 1.0)
TX_COLOR   = (0.2, 1.0, 0.5, 1.0)

# ===================================
# データクリーンアップ関数
# ===================================
def clear_sine_wave_data():
    """このアドオンで生成したオブジェクト、カーブ、マテリアルを全て削除"""
    for obj in list(bpy.data.objects):
        if obj.name.startswith(OBJ_PREFIX):
            bpy.data.objects.remove(obj, do_unlink=True)
    for crv in list(bpy.data.curves):
        if crv.name.startswith(OBJ_PREFIX):
            bpy.data.curves.remove(crv)
    for mat in list(bpy.data.materials):
        if mat.name.startswith(OBJ_PREFIX):
            bpy.data.materials.remove(mat)

# ===================================
# 共通の変位計算 & 波形生成ロジック
# ===================================
def calculate_z_displacement(x, t, props):
    phase_x = x - props.wave_speed_x * (t - props.delay)
    return props.amplitude * math.sin(props.frequency * phase_x) + SINE_LOC_Z_DEFAULT

def create_curve_object(name, thickness, color, collection):
    curve_data = bpy.data.curves.new(name=name, type='CURVE')
    curve_data.dimensions = '3D'
    curve_data.bevel_depth = thickness
    curve_data.bevel_resolution = 4
    
    spline = curve_data.splines.new(type='POLY')
    obj = bpy.data.objects.new(name, curve_data)
    collection.objects.link(obj)
    
    mat = bpy.data.materials.new(name=f"{name}_Mat")
    mat.use_nodes = True
    mat.blend_method = 'BLEND'
    bsdf = mat.node_tree.nodes.get("Principled BSDF")
    if bsdf:
        bsdf.inputs['Base Color'].default_value = color
        if len(color) == 4 and color[3] < 1.0:
            bsdf.inputs['Alpha'].default_value = color[3]
    obj.data.materials.append(mat)
    return spline

def generate_waves(context):
    props = context.scene.sine_wave_props
    
    clear_sine_wave_data()
    
    coll_name = "SineWave_Collection"
    if coll_name in bpy.data.collections:
        coll = bpy.data.collections[coll_name]
    else:
        coll = bpy.data.collections.new(coll_name)
        context.scene.collection.children.link(coll)

    # 1. 初期波形 (t=0)
    if props.init_show:
        spline_init = create_curve_object(f"{OBJ_PREFIX}Init_t0", props.init_thickness, props.init_color, coll)
        spline_init.points.add(props.resolution - 1)
        for i in range(props.resolution):
            x_local = (i / (props.resolution - 1)) * props.length
            y = 0.0 + SINE_LOC_Y_DEFAULT
            z = calculate_z_displacement(x_local, 0.0, props)
            spline_init.points[i].co = (x_local + SINE_LOC_X_DEFAULT, y, z, 1.0)

    # 2. メインの波 (現在の時間)
    if props.main_show:
        spline_main = create_curve_object(f"{OBJ_PREFIX}Main", props.thickness, props.color_main, coll)
        spline_main.points.add(props.resolution - 1)
        for i in range(props.resolution):
            x_local = (i / (props.resolution - 1)) * props.length
            y = props.time_t + SINE_LOC_Y_DEFAULT
            z = calculate_z_displacement(x_local, props.time_t, props)
            spline_main.points[i].co = (x_local + SINE_LOC_X_DEFAULT, y, z, 1.0)

    # 3. 時間軌跡 (x=0)
    if props.traj_show and props.time_max > 0.0:
        spline_traj = create_curve_object(f"{OBJ_PREFIX}Trajectory", props.traj_thickness, props.traj_color, coll)
        spline_traj.points.add(props.resolution - 1)
        for i in range(props.resolution):
            tau = (i / (props.resolution - 1)) * props.time_max
            x_local = 0.0
            y = tau + SINE_LOC_Y_DEFAULT
            z = calculate_z_displacement(x_local, tau, props)
            spline_traj.points[i].co = (x_local + SINE_LOC_X_DEFAULT, y, z, 1.0)

    # 4. t=ax 波面
    if props.tx_show:
        spline_tx = create_curve_object(f"{OBJ_PREFIX}Wave_tx", props.tx_thickness, props.tx_color, coll)
        spline_tx.points.add(props.resolution - 1)
        for i in range(props.resolution):
            max_tx_length = min(props.length, props.time_max / props.tx_slope_a)
            x_local = (i / (props.resolution - 1)) * max_tx_length
            t_local = props.tx_slope_a * x_local
            y = t_local + SINE_LOC_Y_DEFAULT
            z = calculate_z_displacement(x_local, t_local, props)
            spline_tx.points[i].co = (x_local + SINE_LOC_X_DEFAULT, y, z, 1.0)

# ===================================
# リアルタイム反映のコールバック
# ===================================
def update_waves_cb(self, context):
    if context and hasattr(context.scene, 'sine_wave_props'):
        generate_waves(context)

# ===================================
# プロパティ定義
# ===================================
class SineWaveProperties(bpy.types.PropertyGroup):
    amplitude: bpy.props.FloatProperty(name="振幅高さ (Z軸)", default=SINE_AMPLITUDE_DEFAULT, update=update_waves_cb)
    frequency: bpy.props.FloatProperty(name="周波数 (k)", default=SINE_FREQUENCY_DEFAULT, update=update_waves_cb)
    
    length: bpy.props.FloatProperty(name="空間の長さ (X最大)", default=SINE_LENGTH_DEFAULT, update=update_waves_cb)
    time_max: bpy.props.FloatProperty(name="時間の長さ (Y最大)", default=SINE_TIME_MAX_DEFAULT, update=update_waves_cb)
    
    # ======== 変更点 ========
    # soft_min=0.0, soft_max=10.0 を追加し、UIスライダーで直感的に操作できるようにしました
    time_t: bpy.props.FloatProperty(
        name="現在の時間 t", 
        default=SINE_TIME_DEFAULT, 
        soft_min=0.0, 
        soft_max=10.0, 
        update=update_waves_cb
    )
    # ========================
    
    wave_speed_x: bpy.props.FloatProperty(name="X方向速度 (v)", default=SINE_WAVE_SPEED_X_DEFAULT, soft_min=-10.0, soft_max=10.0, update=update_waves_cb)
    delay: bpy.props.FloatProperty(name="開始時間の遅れ", default=SINE_DELAY_DEFAULT, update=update_waves_cb)
    resolution: bpy.props.IntProperty(name="解像度", default=SINE_RESOLUTION_DEFAULT, min=2, update=update_waves_cb)
    
    init_show: bpy.props.BoolProperty(name="初期波 (t=0)", default=True, update=update_waves_cb)
    init_thickness: bpy.props.FloatProperty(name="初期波の太さ", default=0.05, min=0.0, update=update_waves_cb)
    init_color: bpy.props.FloatVectorProperty(name="初期波の色", subtype='COLOR', size=4, default=INIT_COLOR, min=0.0, max=1.0, update=update_waves_cb)

    main_show: bpy.props.BoolProperty(name="時間波形 (t=t)", default=True, update=update_waves_cb)
    thickness: bpy.props.FloatProperty(name="時間波形の太さ", default=0.15, min=0.0, update=update_waves_cb)
    color_main: bpy.props.FloatVectorProperty(name="時間波形の色", subtype='COLOR', size=4, default=MAIN_COLOR, min=0.0, max=1.0, update=update_waves_cb)
    
    traj_show: bpy.props.BoolProperty(name="時間軌跡 (x=0)", default=True, update=update_waves_cb)
    traj_thickness: bpy.props.FloatProperty(name="軌跡の太さ", default=0.1, min=0.0, update=update_waves_cb)
    traj_color: bpy.props.FloatVectorProperty(name="軌跡の色", subtype='COLOR', size=4, default=TRAJ_COLOR, min=0.0, max=1.0, update=update_waves_cb)

    tx_show: bpy.props.BoolProperty(name="t=ax 波面", default=True, update=update_waves_cb)
    tx_slope_a: bpy.props.FloatProperty(name="係数 (a)", default=1.0, min=0.01, max=1.0, update=update_waves_cb)
    tx_thickness: bpy.props.FloatProperty(name="t=ax 波の太さ", default=0.12, min=0.0, update=update_waves_cb)
    tx_color: bpy.props.FloatVectorProperty(name="t=ax 波の色", subtype='COLOR', size=4, default=TX_COLOR, min=0.0, max=1.0, update=update_waves_cb)

# ===================================
# UI パネル
# ===================================
class SINE_WAVE_PT_panel(bpy.types.Panel):
    bl_label = ADDON_TITLE
    bl_idname = f"{PREFIX}_PT_panel"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = "SineWave"

    def draw(self, context):
        layout = self.layout
        props = context.scene.sine_wave_props

        # 1. 基本設定
        box = layout.box()
        box.label(text="物理パラメータ", icon='VIEW_ORTHO')
        box.prop(props, "amplitude")
        box.prop(props, "frequency")
        box.prop(props, "length")
        box.prop(props, "time_max")
        
        box.separator()
        # ======== 変更点 ========
        # slider=True を付けることでスライダーバーとして表示されます
        box.prop(props, "time_t", slider=True)
        # ========================
        
        box.prop(props, "wave_speed_x")
        box.prop(props, "delay")
        box.prop(props, "resolution")
        
        # 2. 波の表示・非表示 トグルボタン群
        box2 = layout.box()
        box2.label(text="波の表示切り替え (ON/OFF)", icon='RESTRICT_VIEW_OFF')
        row = box2.row(align=True)
        row.prop(props, "init_show", toggle=True, text="t=0")
        row.prop(props, "main_show", toggle=True, text="t=t")
        row.prop(props, "traj_show", toggle=True, text="x=0")
        row.prop(props, "tx_show", toggle=True, text="t=ax")

        # 3. 見た目の詳細設定
        box3 = layout.box()
        box3.label(text="色と太さの設定", icon='MATERIAL')
        
        if props.init_show:
            row = box3.row()
            row.label(text="初期 (t=0):")
            row.prop(props, "init_thickness", text="太さ")
            row.prop(props, "init_color", text="")

        if props.main_show:
            row = box3.row()
            row.label(text=f"現在 (t={props.time_t:.1f}):")
            row.prop(props, "thickness", text="太さ")
            row.prop(props, "color_main", text="")
            
        if props.traj_show:
            row = box3.row()
            row.label(text="軌跡 (x=0):")
            row.prop(props, "traj_thickness", text="太さ")
            row.prop(props, "traj_color", text="")

        if props.tx_show:
            box3.separator()
            row_a = box3.row()
            row_a.label(text="波面 (t=ax):")
            row_a.prop(props, "tx_slope_a", text="係数 a", slider=True)
            
            row = box3.row()
            row.label(text="") # 余白用
            row.prop(props, "tx_thickness", text="太さ")
            row.prop(props, "tx_color", text="")

# ===================================
# 登録処理
# ===================================
def setup_viewport_ui():
    for window in bpy.context.window_manager.windows:
        for area in window.screen.areas:
            if area.type == 'VIEW_3D':
                for space in area.spaces:
                    if space.type == 'VIEW_3D':
                        space.shading.type = 'MATERIAL'
                        space.show_region_ui = True
    
    if bpy.context.scene:
        generate_waves(bpy.context)
    return None

classes = (SineWaveProperties, SINE_WAVE_PT_panel)

def register():
    for cls in classes:
        bpy.utils.register_class(cls)
    bpy.types.Scene.sine_wave_props = bpy.props.PointerProperty(type=SineWaveProperties)
    
    bpy.app.timers.register(setup_viewport_ui, first_interval=0.1)

def unregister():
    for cls in reversed(classes):
        bpy.utils.unregister_class(cls)
    del bpy.types.Scene.sine_wave_props
    
    clear_sine_wave_data()

if __name__ == "__main__":
    register()
t=t は いま t=1だけど t=0から t=10 調整できるようにして
bl_info = {
    "name": "Sine Wave Generator (Space & Time Trajectory)",
    "author": "ChatGPT",
    "version": (2, 0, 0),
    "blender": (5, 0, 0),
    "location": "View3D > Sidebar (N Panel)",
    "description": "進行波、時間軌跡、t=ax波面などをリアルタイムで描画します。",
    "category": "3D View",
}

import bpy
import math

# ===================================
# 共通定義 & 初期設定
# ===================================
ADDON_TITLE = "Sine Wave Generator"
PREFIX = "sine_wave"
OBJ_PREFIX = "SINE_WAVE_"

SINE_AMPLITUDE_DEFAULT = 2.0
SINE_FREQUENCY_DEFAULT = 1.0
SINE_LENGTH_DEFAULT = 10.0
SINE_TIME_MAX_DEFAULT = 10.0
SINE_TIME_DEFAULT = 1.0
SINE_DELAY_DEFAULT = 0.0
SINE_RESOLUTION_DEFAULT = 128
SINE_WAVE_SPEED_X_DEFAULT = 1.0

SINE_LOC_X_DEFAULT = 0.0
SINE_LOC_Y_DEFAULT = 0.0
SINE_LOC_Z_DEFAULT = 0.0

INIT_COLOR = (0.5, 0.5, 0.5, 0.8)
MAIN_COLOR = (0.2, 0.6, 1.0, 1.0)
TRAJ_COLOR = (1.0, 0.8, 0.2, 1.0)
TX_COLOR   = (0.2, 1.0, 0.5, 1.0)

# ===================================
# データクリーンアップ関数
# ===================================
def clear_sine_wave_data():
    """このアドオンで生成したオブジェクト、カーブ、マテリアルを全て削除してメモリをクリーンに保つ"""
    for obj in list(bpy.data.objects):
        if obj.name.startswith(OBJ_PREFIX):
            bpy.data.objects.remove(obj, do_unlink=True)
    for crv in list(bpy.data.curves):
        if crv.name.startswith(OBJ_PREFIX):
            bpy.data.curves.remove(crv)
    for mat in list(bpy.data.materials):
        if mat.name.startswith(OBJ_PREFIX):
            bpy.data.materials.remove(mat)

# ===================================
# 共通の変位計算 & 波形生成ロジック
# ===================================
def calculate_z_displacement(x, t, props):
    phase_x = x - props.wave_speed_x * (t - props.delay)
    return props.amplitude * math.sin(props.frequency * phase_x) + SINE_LOC_Z_DEFAULT

def create_curve_object(name, thickness, color, collection):
    curve_data = bpy.data.curves.new(name=name, type='CURVE')
    curve_data.dimensions = '3D'
    curve_data.bevel_depth = thickness
    curve_data.bevel_resolution = 4
    
    spline = curve_data.splines.new(type='POLY')
    obj = bpy.data.objects.new(name, curve_data)
    collection.objects.link(obj)
    
    mat = bpy.data.materials.new(name=f"{name}_Mat")
    mat.use_nodes = True
    mat.blend_method = 'BLEND'
    bsdf = mat.node_tree.nodes.get("Principled BSDF")
    if bsdf:
        bsdf.inputs['Base Color'].default_value = color
        if len(color) == 4 and color[3] < 1.0:
            bsdf.inputs['Alpha'].default_value = color[3]
    obj.data.materials.append(mat)
    return spline

def generate_waves(context):
    """すべての設定を読み取って波を瞬時に生成する"""
    props = context.scene.sine_wave_props
    
    clear_sine_wave_data()
    
    # アドオン専用コレクションの取得・作成
    coll_name = "SineWave_Collection"
    if coll_name in bpy.data.collections:
        coll = bpy.data.collections[coll_name]
    else:
        coll = bpy.data.collections.new(coll_name)
        context.scene.collection.children.link(coll)

    # 1. 初期波形 (t=0)
    if props.init_show:
        spline_init = create_curve_object(f"{OBJ_PREFIX}Init_t0", props.init_thickness, props.init_color, coll)
        spline_init.points.add(props.resolution - 1)
        for i in range(props.resolution):
            x_local = (i / (props.resolution - 1)) * props.length
            y = 0.0 + SINE_LOC_Y_DEFAULT
            z = calculate_z_displacement(x_local, 0.0, props)
            spline_init.points[i].co = (x_local + SINE_LOC_X_DEFAULT, y, z, 1.0)

    # 2. メインの波 (現在の時間)
    if props.main_show:
        spline_main = create_curve_object(f"{OBJ_PREFIX}Main", props.thickness, props.color_main, coll)
        spline_main.points.add(props.resolution - 1)
        for i in range(props.resolution):
            x_local = (i / (props.resolution - 1)) * props.length
            y = props.time_t + SINE_LOC_Y_DEFAULT
            z = calculate_z_displacement(x_local, props.time_t, props)
            spline_main.points[i].co = (x_local + SINE_LOC_X_DEFAULT, y, z, 1.0)

    # 3. 時間軌跡 (x=0)
    if props.traj_show and props.time_max > 0.0:
        spline_traj = create_curve_object(f"{OBJ_PREFIX}Trajectory", props.traj_thickness, props.traj_color, coll)
        spline_traj.points.add(props.resolution - 1)
        for i in range(props.resolution):
            tau = (i / (props.resolution - 1)) * props.time_max
            x_local = 0.0
            y = tau + SINE_LOC_Y_DEFAULT
            z = calculate_z_displacement(x_local, tau, props)
            spline_traj.points[i].co = (x_local + SINE_LOC_X_DEFAULT, y, z, 1.0)

    # 4. t=ax 波面
    if props.tx_show:
        spline_tx = create_curve_object(f"{OBJ_PREFIX}Wave_tx", props.tx_thickness, props.tx_color, coll)
        spline_tx.points.add(props.resolution - 1)
        for i in range(props.resolution):
            max_tx_length = min(props.length, props.time_max / props.tx_slope_a)
            x_local = (i / (props.resolution - 1)) * max_tx_length
            t_local = props.tx_slope_a * x_local
            y = t_local + SINE_LOC_Y_DEFAULT
            z = calculate_z_displacement(x_local, t_local, props)
            spline_tx.points[i].co = (x_local + SINE_LOC_X_DEFAULT, y, z, 1.0)

# ===================================
# リアルタイム反映のコールバック
# ===================================
def update_waves_cb(self, context):
    """プロパティが変更された瞬間に呼び出され、描画を更新する"""
    if context and hasattr(context.scene, 'sine_wave_props'):
        generate_waves(context)

# ===================================
# プロパティ定義 (全てに update=update_waves_cb を追加)
# ===================================
class SineWaveProperties(bpy.types.PropertyGroup):
    amplitude: bpy.props.FloatProperty(name="振幅高さ (Z軸)", default=SINE_AMPLITUDE_DEFAULT, update=update_waves_cb)
    frequency: bpy.props.FloatProperty(name="周波数 (k)", default=SINE_FREQUENCY_DEFAULT, update=update_waves_cb)
    
    length: bpy.props.FloatProperty(name="空間の長さ (X最大)", default=SINE_LENGTH_DEFAULT, update=update_waves_cb)
    time_max: bpy.props.FloatProperty(name="時間の長さ (Y最大)", default=SINE_TIME_MAX_DEFAULT, update=update_waves_cb)
    
    time_t: bpy.props.FloatProperty(name="現在の時間 t", default=SINE_TIME_DEFAULT, update=update_waves_cb)
    wave_speed_x: bpy.props.FloatProperty(name="X方向速度 (v)", default=SINE_WAVE_SPEED_X_DEFAULT, soft_min=-10.0, soft_max=10.0, update=update_waves_cb)
    delay: bpy.props.FloatProperty(name="開始時間の遅れ", default=SINE_DELAY_DEFAULT, update=update_waves_cb)
    resolution: bpy.props.IntProperty(name="解像度", default=SINE_RESOLUTION_DEFAULT, min=2, update=update_waves_cb)
    
    init_show: bpy.props.BoolProperty(name="初期波 (t=0)", default=True, update=update_waves_cb)
    init_thickness: bpy.props.FloatProperty(name="初期波の太さ", default=0.05, min=0.0, update=update_waves_cb)
    init_color: bpy.props.FloatVectorProperty(name="初期波の色", subtype='COLOR', size=4, default=INIT_COLOR, min=0.0, max=1.0, update=update_waves_cb)

    main_show: bpy.props.BoolProperty(name="時間波形 (t=t)", default=True, update=update_waves_cb)
    thickness: bpy.props.FloatProperty(name="時間波形の太さ", default=0.15, min=0.0, update=update_waves_cb)
    color_main: bpy.props.FloatVectorProperty(name="時間波形の色", subtype='COLOR', size=4, default=MAIN_COLOR, min=0.0, max=1.0, update=update_waves_cb)
    
    traj_show: bpy.props.BoolProperty(name="時間軌跡 (x=0)", default=True, update=update_waves_cb)
    traj_thickness: bpy.props.FloatProperty(name="軌跡の太さ", default=0.1, min=0.0, update=update_waves_cb)
    traj_color: bpy.props.FloatVectorProperty(name="軌跡の色", subtype='COLOR', size=4, default=TRAJ_COLOR, min=0.0, max=1.0, update=update_waves_cb)

    tx_show: bpy.props.BoolProperty(name="t=ax 波面", default=True, update=update_waves_cb)
    tx_slope_a: bpy.props.FloatProperty(name="係数 (a)", default=1.0, min=0.01, max=1.0, update=update_waves_cb)
    tx_thickness: bpy.props.FloatProperty(name="t=ax 波の太さ", default=0.12, min=0.0, update=update_waves_cb)
    tx_color: bpy.props.FloatVectorProperty(name="t=ax 波の色", subtype='COLOR', size=4, default=TX_COLOR, min=0.0, max=1.0, update=update_waves_cb)

# ===================================
# UI パネル
# ===================================
class SINE_WAVE_PT_panel(bpy.types.Panel):
    bl_label = ADDON_TITLE
    bl_idname = f"{PREFIX}_PT_panel"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = "SineWave"

    def draw(self, context):
        layout = self.layout
        props = context.scene.sine_wave_props

        # 1. 基本設定
        box = layout.box()
        box.label(text="物理パラメータ", icon='VIEW_ORTHO')
        box.prop(props, "amplitude")
        box.prop(props, "frequency")
        box.prop(props, "length")
        box.prop(props, "time_max")
        
        box.separator()
        box.prop(props, "time_t")
        box.prop(props, "wave_speed_x")
        box.prop(props, "delay")
        box.prop(props, "resolution")
        
        # 2. 波の表示・非表示 トグルボタン群
        box2 = layout.box()
        box2.label(text="波の表示切り替え (ON/OFF)", icon='RESTRICT_VIEW_OFF')
        row = box2.row(align=True)
        row.prop(props, "init_show", toggle=True, text="t=0")
        row.prop(props, "main_show", toggle=True, text="t=t")
        row.prop(props, "traj_show", toggle=True, text="x=0")
        row.prop(props, "tx_show", toggle=True, text="t=ax")

        # 3. 見た目の詳細設定 (ONになっているものだけ表示)
        box3 = layout.box()
        box3.label(text="色と太さの設定", icon='MATERIAL')
        
        if props.init_show:
            row = box3.row()
            row.label(text="初期 (t=0):")
            row.prop(props, "init_thickness", text="太さ")
            row.prop(props, "init_color", text="")

        if props.main_show:
            row = box3.row()
            row.label(text=f"現在 (t={props.time_t:.1f}):")
            row.prop(props, "thickness", text="太さ")
            row.prop(props, "color_main", text="")
            
        if props.traj_show:
            row = box3.row()
            row.label(text="軌跡 (x=0):")
            row.prop(props, "traj_thickness", text="太さ")
            row.prop(props, "traj_color", text="")

        if props.tx_show:
            box3.separator()
            row_a = box3.row()
            row_a.label(text="波面 (t=ax):")
            row_a.prop(props, "tx_slope_a", text="係数 a")
            
            row = box3.row()
            row.label(text="") # 余白用
            row.prop(props, "tx_thickness", text="太さ")
            row.prop(props, "tx_color", text="")

# ===================================
# 登録処理
# ===================================
def setup_viewport_ui():
    """初期化時にNパネルを開き、1回目の描画を行う"""
    for window in bpy.context.window_manager.windows:
        for area in window.screen.areas:
            if area.type == 'VIEW_3D':
                for space in area.spaces:
                    if space.type == 'VIEW_3D':
                        space.shading.type = 'MATERIAL'
                        space.show_region_ui = True
    
    # 有効化時に一度だけ自動生成を実行
    if bpy.context.scene:
        generate_waves(bpy.context)
    return None

classes = (SineWaveProperties, SINE_WAVE_PT_panel)

def register():
    for cls in classes:
        bpy.utils.register_class(cls)
    bpy.types.Scene.sine_wave_props = bpy.props.PointerProperty(type=SineWaveProperties)
    
    # アドオン有効化の0.1秒後に初期セットアップと初回生成を実行
    bpy.app.timers.register(setup_viewport_ui, first_interval=0.1)

def unregister():
    for cls in reversed(classes):
        bpy.utils.unregister_class(cls)
    del bpy.types.Scene.sine_wave_props
    
    # アンインストール・無効化時にオブジェクトをきれいに消去
    clear_sine_wave_data()

if __name__ == "__main__":
    register()
bl_info = {
    "name": "Sine Wave Generator (Space & Time Trajectory)",
    "author": "ChatGPT",
    "version": (2, 0, 0),
    "blender": (5, 0, 0),
    "location": "View3D > Sidebar (N Panel)",
    "description": "進行波、時間軌跡、t=ax波面などをリアルタイムで描画します。",
    "category": "3D View",
}

import bpy
import math

# ===================================
# 共通定義 & 初期設定
# ===================================
ADDON_TITLE = "Sine Wave Generator"
PREFIX = "sine_wave"
OBJ_PREFIX = "SINE_WAVE_"

SINE_AMPLITUDE_DEFAULT = 2.0
SINE_FREQUENCY_DEFAULT = 1.0
SINE_LENGTH_DEFAULT = 10.0
SINE_TIME_MAX_DEFAULT = 10.0
SINE_TIME_DEFAULT = 1.0
SINE_DELAY_DEFAULT = 0.0
SINE_RESOLUTION_DEFAULT = 128
SINE_WAVE_SPEED_X_DEFAULT = 1.0

SINE_LOC_X_DEFAULT = 0.0
SINE_LOC_Y_DEFAULT = 0.0
SINE_LOC_Z_DEFAULT = 0.0

INIT_COLOR = (0.5, 0.5, 0.5, 0.8)
MAIN_COLOR = (0.2, 0.6, 1.0, 1.0)
TRAJ_COLOR = (1.0, 0.8, 0.2, 1.0)
TX_COLOR   = (0.2, 1.0, 0.5, 1.0)

# ===================================
# データクリーンアップ関数
# ===================================
def clear_sine_wave_data():
    """このアドオンで生成したオブジェクト、カーブ、マテリアルを全て削除してメモリをクリーンに保つ"""
    for obj in list(bpy.data.objects):
        if obj.name.startswith(OBJ_PREFIX):
            bpy.data.objects.remove(obj, do_unlink=True)
    for crv in list(bpy.data.curves):
        if crv.name.startswith(OBJ_PREFIX):
            bpy.data.curves.remove(crv)
    for mat in list(bpy.data.materials):
        if mat.name.startswith(OBJ_PREFIX):
            bpy.data.materials.remove(mat)

# ===================================
# 共通の変位計算 & 波形生成ロジック
# ===================================
def calculate_z_displacement(x, t, props):
    phase_x = x - props.wave_speed_x * (t - props.delay)
    return props.amplitude * math.sin(props.frequency * phase_x) + SINE_LOC_Z_DEFAULT

def create_curve_object(name, thickness, color, collection):
    curve_data = bpy.data.curves.new(name=name, type='CURVE')
    curve_data.dimensions = '3D'
    curve_data.bevel_depth = thickness
    curve_data.bevel_resolution = 4
    
    spline = curve_data.splines.new(type='POLY')
    obj = bpy.data.objects.new(name, curve_data)
    collection.objects.link(obj)
    
    mat = bpy.data.materials.new(name=f"{name}_Mat")
    mat.use_nodes = True
    mat.blend_method = 'BLEND'
    bsdf = mat.node_tree.nodes.get("Principled BSDF")
    if bsdf:
        bsdf.inputs['Base Color'].default_value = color
        if len(color) == 4 and color[3] < 1.0:
            bsdf.inputs['Alpha'].default_value = color[3]
    obj.data.materials.append(mat)
    return spline

def generate_waves(context):
    """すべての設定を読み取って波を瞬時に生成する"""
    props = context.scene.sine_wave_props
    
    clear_sine_wave_data()
    
    # アドオン専用コレクションの取得・作成
    coll_name = "SineWave_Collection"
    if coll_name in bpy.data.collections:
        coll = bpy.data.collections[coll_name]
    else:
        coll = bpy.data.collections.new(coll_name)
        context.scene.collection.children.link(coll)

    # 1. 初期波形 (t=0)
    if props.init_show:
        spline_init = create_curve_object(f"{OBJ_PREFIX}Init_t0", props.init_thickness, props.init_color, coll)
        spline_init.points.add(props.resolution - 1)
        for i in range(props.resolution):
            x_local = (i / (props.resolution - 1)) * props.length
            y = 0.0 + SINE_LOC_Y_DEFAULT
            z = calculate_z_displacement(x_local, 0.0, props)
            spline_init.points[i].co = (x_local + SINE_LOC_X_DEFAULT, y, z, 1.0)

    # 2. メインの波 (現在の時間)
    if props.main_show:
        spline_main = create_curve_object(f"{OBJ_PREFIX}Main", props.thickness, props.color_main, coll)
        spline_main.points.add(props.resolution - 1)
        for i in range(props.resolution):
            x_local = (i / (props.resolution - 1)) * props.length
            y = props.time_t + SINE_LOC_Y_DEFAULT
            z = calculate_z_displacement(x_local, props.time_t, props)
            spline_main.points[i].co = (x_local + SINE_LOC_X_DEFAULT, y, z, 1.0)

    # 3. 時間軌跡 (x=0)
    if props.traj_show and props.time_max > 0.0:
        spline_traj = create_curve_object(f"{OBJ_PREFIX}Trajectory", props.traj_thickness, props.traj_color, coll)
        spline_traj.points.add(props.resolution - 1)
        for i in range(props.resolution):
            tau = (i / (props.resolution - 1)) * props.time_max
            x_local = 0.0
            y = tau + SINE_LOC_Y_DEFAULT
            z = calculate_z_displacement(x_local, tau, props)
            spline_traj.points[i].co = (x_local + SINE_LOC_X_DEFAULT, y, z, 1.0)

    # 4. t=ax 波面
    if props.tx_show:
        spline_tx = create_curve_object(f"{OBJ_PREFIX}Wave_tx", props.tx_thickness, props.tx_color, coll)
        spline_tx.points.add(props.resolution - 1)
        for i in range(props.resolution):
            max_tx_length = min(props.length, props.time_max / props.tx_slope_a)
            x_local = (i / (props.resolution - 1)) * max_tx_length
            t_local = props.tx_slope_a * x_local
            y = t_local + SINE_LOC_Y_DEFAULT
            z = calculate_z_displacement(x_local, t_local, props)
            spline_tx.points[i].co = (x_local + SINE_LOC_X_DEFAULT, y, z, 1.0)

# ===================================
# リアルタイム反映のコールバック
# ===================================
def update_waves_cb(self, context):
    """プロパティが変更された瞬間に呼び出され、描画を更新する"""
    if context and hasattr(context.scene, 'sine_wave_props'):
        generate_waves(context)

# ===================================
# プロパティ定義 (全てに update=update_waves_cb を追加)
# ===================================
class SineWaveProperties(bpy.types.PropertyGroup):
    amplitude: bpy.props.FloatProperty(name="振幅高さ (Z軸)", default=SINE_AMPLITUDE_DEFAULT, update=update_waves_cb)
    frequency: bpy.props.FloatProperty(name="周波数 (k)", default=SINE_FREQUENCY_DEFAULT, update=update_waves_cb)
    
    length: bpy.props.FloatProperty(name="空間の長さ (X最大)", default=SINE_LENGTH_DEFAULT, update=update_waves_cb)
    time_max: bpy.props.FloatProperty(name="時間の長さ (Y最大)", default=SINE_TIME_MAX_DEFAULT, update=update_waves_cb)
    
    time_t: bpy.props.FloatProperty(name="現在の時間 t", default=SINE_TIME_DEFAULT, update=update_waves_cb)
    wave_speed_x: bpy.props.FloatProperty(name="X方向速度 (v)", default=SINE_WAVE_SPEED_X_DEFAULT, soft_min=-10.0, soft_max=10.0, update=update_waves_cb)
    delay: bpy.props.FloatProperty(name="開始時間の遅れ", default=SINE_DELAY_DEFAULT, update=update_waves_cb)
    resolution: bpy.props.IntProperty(name="解像度", default=SINE_RESOLUTION_DEFAULT, min=2, update=update_waves_cb)
    
    init_show: bpy.props.BoolProperty(name="初期波 (t=0)", default=True, update=update_waves_cb)
    init_thickness: bpy.props.FloatProperty(name="初期波の太さ", default=0.05, min=0.0, update=update_waves_cb)
    init_color: bpy.props.FloatVectorProperty(name="初期波の色", subtype='COLOR', size=4, default=INIT_COLOR, min=0.0, max=1.0, update=update_waves_cb)

    main_show: bpy.props.BoolProperty(name="時間波形 (t=t)", default=True, update=update_waves_cb)
    thickness: bpy.props.FloatProperty(name="時間波形の太さ", default=0.15, min=0.0, update=update_waves_cb)
    color_main: bpy.props.FloatVectorProperty(name="時間波形の色", subtype='COLOR', size=4, default=MAIN_COLOR, min=0.0, max=1.0, update=update_waves_cb)
    
    traj_show: bpy.props.BoolProperty(name="時間軌跡 (x=0)", default=True, update=update_waves_cb)
    traj_thickness: bpy.props.FloatProperty(name="軌跡の太さ", default=0.1, min=0.0, update=update_waves_cb)
    traj_color: bpy.props.FloatVectorProperty(name="軌跡の色", subtype='COLOR', size=4, default=TRAJ_COLOR, min=0.0, max=1.0, update=update_waves_cb)

    tx_show: bpy.props.BoolProperty(name="t=ax 波面", default=True, update=update_waves_cb)
    tx_slope_a: bpy.props.FloatProperty(name="係数 (a)", default=1.0, min=0.01, max=1.0, update=update_waves_cb)
    tx_thickness: bpy.props.FloatProperty(name="t=ax 波の太さ", default=0.12, min=0.0, update=update_waves_cb)
    tx_color: bpy.props.FloatVectorProperty(name="t=ax 波の色", subtype='COLOR', size=4, default=TX_COLOR, min=0.0, max=1.0, update=update_waves_cb)

# ===================================
# UI パネル
# ===================================
class SINE_WAVE_PT_panel(bpy.types.Panel):
    bl_label = ADDON_TITLE
    bl_idname = f"{PREFIX}_PT_panel"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = "SineWave"

    def draw(self, context):
        layout = self.layout
        props = context.scene.sine_wave_props

        # 1. 基本設定
        box = layout.box()
        box.label(text="物理パラメータ", icon='VIEW_ORTHO')
        box.prop(props, "amplitude")
        box.prop(props, "frequency")
        box.prop(props, "length")
        box.prop(props, "time_max")
        
        box.separator()
        box.prop(props, "time_t")
        box.prop(props, "wave_speed_x")
        box.prop(props, "delay")
        box.prop(props, "resolution")
        
        # 2. 波の表示・非表示 トグルボタン群
        box2 = layout.box()
        box2.label(text="波の表示切り替え (ON/OFF)", icon='RESTRICT_VIEW_OFF')
        row = box2.row(align=True)
        row.prop(props, "init_show", toggle=True, text="t=0")
        row.prop(props, "main_show", toggle=True, text="t=t")
        row.prop(props, "traj_show", toggle=True, text="x=0")
        row.prop(props, "tx_show", toggle=True, text="t=ax")

        # 3. 見た目の詳細設定 (ONになっているものだけ表示)
        box3 = layout.box()
        box3.label(text="色と太さの設定", icon='MATERIAL')
        
        if props.init_show:
            row = box3.row()
            row.label(text="初期 (t=0):")
            row.prop(props, "init_thickness", text="太さ")
            row.prop(props, "init_color", text="")

        if props.main_show:
            row = box3.row()
            row.label(text=f"現在 (t={props.time_t:.1f}):")
            row.prop(props, "thickness", text="太さ")
            row.prop(props, "color_main", text="")
            
        if props.traj_show:
            row = box3.row()
            row.label(text="軌跡 (x=0):")
            row.prop(props, "traj_thickness", text="太さ")
            row.prop(props, "traj_color", text="")

        if props.tx_show:
            box3.separator()
            row_a = box3.row()
            row_a.label(text="波面 (t=ax):")
            row_a.prop(props, "tx_slope_a", text="係数 a")
            
            row = box3.row()
            row.label(text="") # 余白用
            row.prop(props, "tx_thickness", text="太さ")
            row.prop(props, "tx_color", text="")

# ===================================
# 登録処理
# ===================================
def setup_viewport_ui():
    """初期化時にNパネルを開き、1回目の描画を行う"""
    for window in bpy.context.window_manager.windows:
        for area in window.screen.areas:
            if area.type == 'VIEW_3D':
                for space in area.spaces:
                    if space.type == 'VIEW_3D':
                        space.shading.type = 'MATERIAL'
                        space.show_region_ui = True
    
    # 有効化時に一度だけ自動生成を実行
    if bpy.context.scene:
        generate_waves(bpy.context)
    return None

classes = (SineWaveProperties, SINE_WAVE_PT_panel)

def register():
    for cls in classes:
        bpy.utils.register_class(cls)
    bpy.types.Scene.sine_wave_props = bpy.props.PointerProperty(type=SineWaveProperties)
    
    # アドオン有効化の0.1秒後に初期セットアップと初回生成を実行
    bpy.app.timers.register(setup_viewport_ui, first_interval=0.1)

def unregister():
    for cls in reversed(classes):
        bpy.utils.unregister_class(cls)
    del bpy.types.Scene.sine_wave_props
    
    # アンインストール・無効化時にオブジェクトをきれいに消去
    clear_sine_wave_data()

if __name__ == "__main__":
    register()
標示非表示 のボタン それぞれと
数値 リアルタイム繁栄
bl_info = {
    "name": "Sine Wave Generator (Space & Time Trajectory)",
    "author": "ChatGPT",
    "version": (1, 9, 0),
    "blender": (5, 0, 0),
    "location": "View3D > Sidebar (N Panel)",
    "description": "進行波、x=0の時間軌跡(t=0〜10)、t=axの波面などを描画します。",
    "category": "3D View",
}

import bpy
import math

# ===================================
# 共通定義 & 初期設定
# ===================================
ADDON_TITLE = "Sine Wave Generator"
PREFIX = "sine_wave"

SINE_AMPLITUDE_DEFAULT = 2.0
SINE_FREQUENCY_DEFAULT = 1.0
SINE_LENGTH_DEFAULT = 10.0
SINE_TIME_MAX_DEFAULT = 10.0
SINE_TIME_DEFAULT = 1.0
SINE_DELAY_DEFAULT = 0.0
SINE_RESOLUTION_DEFAULT = 128
SINE_WAVE_SPEED_X_DEFAULT = 1.0

SINE_LOC_X_DEFAULT = 0.0
SINE_LOC_Y_DEFAULT = 0.0
SINE_LOC_Z_DEFAULT = 0.0

INIT_COLOR = (0.5, 0.5, 0.5, 0.8)
MAIN_COLOR = (0.2, 0.6, 1.0, 1.0)
TRAJ_COLOR = (1.0, 0.8, 0.2, 1.0)
TX_COLOR   = (0.2, 1.0, 0.5, 1.0)

# ===================================
# 共通の変位計算関数
# ===================================
def calculate_z_displacement(x, t, props):
    """
    空間(x) が主役の標準的な進行波の式: (x - v*t)
    これにより x>0 で最初に山になります。
    """
    phase_x = x - props.wave_speed_x * (t - props.delay)
    return props.amplitude * math.sin(props.frequency * phase_x) + SINE_LOC_Z_DEFAULT

# ===================================
# プロパティ定義
# ===================================
class SineWaveProperties(bpy.types.PropertyGroup):
    amplitude: bpy.props.FloatProperty(name="振幅高さ (Z軸)", default=SINE_AMPLITUDE_DEFAULT)
    frequency: bpy.props.FloatProperty(name="周波数 (k)", default=SINE_FREQUENCY_DEFAULT)
    
    length: bpy.props.FloatProperty(name="空間の長さ (X最大)", default=SINE_LENGTH_DEFAULT)
    time_max: bpy.props.FloatProperty(name="時間の長さ (Y最大)", default=SINE_TIME_MAX_DEFAULT)
    
    time_t: bpy.props.FloatProperty(name="現在の時間 t", default=SINE_TIME_DEFAULT)
    wave_speed_x: bpy.props.FloatProperty(name="X方向速度 (v)", default=SINE_WAVE_SPEED_X_DEFAULT, soft_min=-10.0, soft_max=10.0)
    delay: bpy.props.FloatProperty(name="開始時間の遅れ", default=SINE_DELAY_DEFAULT)
    resolution: bpy.props.IntProperty(name="解像度", default=SINE_RESOLUTION_DEFAULT, min=2)
    
    # 1. 初期波 (t=0)
    init_show: bpy.props.BoolProperty(name="初期波 (t=0) を描画", default=True)
    init_thickness: bpy.props.FloatProperty(name="初期波の太さ", default=0.05, min=0.0)
    init_color: bpy.props.FloatVectorProperty(name="初期波の色", subtype='COLOR', size=4, default=INIT_COLOR, min=0.0, max=1.0)

    # 2. メイン波 (t=t)
    main_show: bpy.props.BoolProperty(name="時間波形 (現在の t) を描画", default=True)
    thickness: bpy.props.FloatProperty(name="時間波形の太さ", default=0.15, min=0.0)
    color_main: bpy.props.FloatVectorProperty(name="時間波形の色", subtype='COLOR', size=4, default=MAIN_COLOR, min=0.0, max=1.0)
    
    # 3. 軌跡 (x=0)
    traj_show: bpy.props.BoolProperty(name="時間軌跡 (x=0) を描画", default=True)
    traj_thickness: bpy.props.FloatProperty(name="軌跡の太さ", default=0.1, min=0.0)
    traj_color: bpy.props.FloatVectorProperty(name="軌跡の色", subtype='COLOR', size=4, default=TRAJ_COLOR, min=0.0, max=1.0)

    # 4. t=ax 波面
    tx_show: bpy.props.BoolProperty(name="t=ax 波面を描画", default=True)
    tx_slope_a: bpy.props.FloatProperty(
        name="係数 (a)", default=1.0, min=0.01, max=1.0, 
        description="t = a * x 波面の係数a"
    )
    tx_thickness: bpy.props.FloatProperty(name="t=ax 波の太さ", default=0.12, min=0.0)
    tx_color: bpy.props.FloatVectorProperty(name="t=ax 波の色", subtype='COLOR', size=4, default=TX_COLOR, min=0.0, max=1.0)

# ===================================
# オペレーター (生成処理)
# ===================================
class SINE_WAVE_OT_generate(bpy.types.Operator):
    bl_idname = f"{PREFIX}.generate"
    bl_label = "波と軌跡を生成"

    def create_curve_object(self, name, thickness, color, collection):
        curve_data = bpy.data.curves.new(name=name, type='CURVE')
        curve_data.dimensions = '3D'
        curve_data.bevel_depth = thickness
        curve_data.bevel_resolution = 4
        
        spline = curve_data.splines.new(type='POLY')
        
        obj = bpy.data.objects.new(name, curve_data)
        collection.objects.link(obj)
        
        mat = bpy.data.materials.new(name=f"{name}_Mat")
        mat.use_nodes = True
        mat.blend_method = 'BLEND'
        bsdf = mat.node_tree.nodes.get("Principled BSDF")
        if bsdf:
            bsdf.inputs['Base Color'].default_value = color
            if len(color) == 4 and color[3] < 1.0:
                bsdf.inputs['Alpha'].default_value = color[3]
        obj.data.materials.append(mat)
        
        return spline

    def execute(self, context):
        props = context.scene.sine_wave_props
        collection = context.collection

        # 1. 初期波形 (t=0)
        if props.init_show:
            spline_init = self.create_curve_object("Wave_Init_t0", props.init_thickness, props.init_color, collection)
            spline_init.points.add(props.resolution - 1)
            for i in range(props.resolution):
                x_local = (i / (props.resolution - 1)) * props.length
                y = 0.0 + SINE_LOC_Y_DEFAULT
                z = calculate_z_displacement(x_local, 0.0, props)
                spline_init.points[i].co = (x_local + SINE_LOC_X_DEFAULT, y, z, 1.0)

        # 2. メインの波 (現在の時間)
        if props.main_show:
            spline_main = self.create_curve_object(f"Wave_Main_t{props.time_t:.1f}", props.thickness, props.color_main, collection)
            spline_main.points.add(props.resolution - 1)
            for i in range(props.resolution):
                x_local = (i / (props.resolution - 1)) * props.length
                y = props.time_t + SINE_LOC_Y_DEFAULT
                z = calculate_z_displacement(x_local, props.time_t, props)
                spline_main.points[i].co = (x_local + SINE_LOC_X_DEFAULT, y, z, 1.0)

        # 3. 時間軌跡 (x=0)
        if props.traj_show and props.time_max > 0.0:
            spline_traj = self.create_curve_object("Trajectory_x0", props.traj_thickness, props.traj_color, collection)
            spline_traj.points.add(props.resolution - 1)
            for i in range(props.resolution):
                tau = (i / (props.resolution - 1)) * props.time_max
                x_local = 0.0
                y = tau + SINE_LOC_Y_DEFAULT
                z = calculate_z_displacement(x_local, tau, props)
                spline_traj.points[i].co = (x_local + SINE_LOC_X_DEFAULT, y, z, 1.0)

        # 4. t=ax 波面
        if props.tx_show:
            spline_tx = self.create_curve_object(f"Wave_t_equals_{props.tx_slope_a:.2f}x", props.tx_thickness, props.tx_color, collection)
            spline_tx.points.add(props.resolution - 1)
            for i in range(props.resolution):
                # 描画距離は「Xの最大長」か「t=time_max に達するXの長さ (time_max / a)」のどちらか短い方まで
                max_tx_length = min(props.length, props.time_max / props.tx_slope_a)
                x_local = (i / (props.resolution - 1)) * max_tx_length
                
                t_local = props.tx_slope_a * x_local  # t = ax
                
                y = t_local + SINE_LOC_Y_DEFAULT
                z = calculate_z_displacement(x_local, t_local, props)
                spline_tx.points[i].co = (x_local + SINE_LOC_X_DEFAULT, y, z, 1.0)

        return {'FINISHED'}

# ===================================
# UI パネル・登録処理
# ===================================
class SINE_WAVE_PT_panel(bpy.types.Panel):
    bl_label = ADDON_TITLE
    bl_idname = f"{PREFIX}_PT_panel"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = "SineWave"

    def draw(self, context):
        layout = self.layout
        props = context.scene.sine_wave_props

        box = layout.box()
        box.label(text="基本設定", icon='VIEW_ORTHO')
        box.prop(props, "amplitude")
        box.prop(props, "frequency")
        box.prop(props, "length")
        box.prop(props, "time_max")
        box.prop(props, "time_t")
        box.prop(props, "wave_speed_x")
        box.prop(props, "delay")
        box.prop(props, "resolution")
        
        box2 = layout.box()
        box2.label(text="波の描画設定", icon='OUTLINER_OB_CURVE')
        
        box2.prop(props, "init_show", icon='TIME')
        if props.init_show:
            row = box2.row()
            row.prop(props, "init_thickness", text="太さ")
            row.prop(props, "init_color", text="")

        box2.prop(props, "main_show", text=f"時間波形 (t={props.time_t:.1f})", icon='MOD_WAVE')
        if props.main_show:
            row = box2.row()
            row.prop(props, "thickness", text="太さ")
            row.prop(props, "color_main", text="")
            
        box2.prop(props, "traj_show", text=f"時間軌跡 (t=0〜{props.time_max:.0f})", icon='ANIM')
        if props.traj_show:
            row = box2.row()
            row.prop(props, "traj_thickness", text="太さ")
            row.prop(props, "traj_color", text="")

        # 4. t=ax 波面 の設定UI
        box2.prop(props, "tx_show", text=f"t={props.tx_slope_a:.2f}x 波面", icon='CON_TRANSLIKE')
        if props.tx_show:
            row_a = box2.row()
            row_a.prop(props, "tx_slope_a", slider=True)
            row = box2.row()
            row.prop(props, "tx_thickness", text="太さ")
            row.prop(props, "tx_color", text="")
        
        layout.separator()
        row = layout.row()
        row.scale_y = 1.5
        row.operator(SINE_WAVE_OT_generate.bl_idname, text="波と軌跡を作成", icon='PLAY')

def setup_viewport_ui():
    for window in bpy.context.window_manager.windows:
        for area in window.screen.areas:
            if area.type == 'VIEW_3D':
                for space in area.spaces:
                    if space.type == 'VIEW_3D':
                        space.shading.type = 'MATERIAL'
                        space.show_region_ui = True
    return None

classes = (SineWaveProperties, SINE_WAVE_OT_generate, SINE_WAVE_PT_panel)

def register():
    for cls in classes:
        bpy.utils.register_class(cls)
    bpy.types.Scene.sine_wave_props = bpy.props.PointerProperty(type=SineWaveProperties)
    bpy.app.timers.register(setup_viewport_ui, first_interval=0.1)

def unregister():
    for cls in reversed(classes):
        bpy.utils.unregister_class(cls)
    del bpy.types.Scene.sine_wave_props

if __name__ == "__main__":
    register()
t=x 波面じゃなく t=ax 波面にして a=0.01 から1で z軸振幅表示
bl_info = {
    "name": "Sine Wave Generator (Space & Time Trajectory)",
    "author": "ChatGPT",
    "version": (1, 8, 0),
    "blender": (5, 0, 0),
    "location": "View3D > Sidebar (N Panel)",
    "description": "進行波、x=0の時間軌跡(t=0〜10)、t=xの波面などを描画します。",
    "category": "3D View",
}

import bpy
import math

# ===================================
# 共通定義 & 初期設定
# ===================================
ADDON_TITLE = "Sine Wave Generator"
PREFIX = "sine_wave"

SINE_AMPLITUDE_DEFAULT = 2.0
SINE_FREQUENCY_DEFAULT = 1.0
SINE_LENGTH_DEFAULT = 10.0
SINE_TIME_MAX_DEFAULT = 10.0
SINE_TIME_DEFAULT = 1.0
SINE_DELAY_DEFAULT = 0.0
SINE_RESOLUTION_DEFAULT = 128
SINE_WAVE_SPEED_X_DEFAULT = 1.0

SINE_LOC_X_DEFAULT = 0.0
SINE_LOC_Y_DEFAULT = 0.0
SINE_LOC_Z_DEFAULT = 0.0

INIT_COLOR = (0.5, 0.5, 0.5, 0.8)
MAIN_COLOR = (0.2, 0.6, 1.0, 1.0)
TRAJ_COLOR = (1.0, 0.8, 0.2, 1.0)
TX_COLOR   = (0.2, 1.0, 0.5, 1.0)

# ===================================
# 共通の変位計算関数
# ===================================
def calculate_z_displacement(x, t, props):
    """
    【修正】空間(x) が主役の標準的な進行波の式: (x - v*t)
    これにより x>0 で最初に山になります。
    (※物理法則として、+Xへ進む波の場合 t>0 の時間軌跡は必ず谷から始まります)
    """
    phase_x = x - props.wave_speed_x * (t - props.delay)
    return props.amplitude * math.sin(props.frequency * phase_x) + SINE_LOC_Z_DEFAULT

# ===================================
# プロパティ定義
# ===================================
class SineWaveProperties(bpy.types.PropertyGroup):
    amplitude: bpy.props.FloatProperty(name="振幅高さ (Z軸)", default=SINE_AMPLITUDE_DEFAULT)
    frequency: bpy.props.FloatProperty(name="周波数 (k)", default=SINE_FREQUENCY_DEFAULT)
    
    length: bpy.props.FloatProperty(name="空間の長さ (X最大)", default=SINE_LENGTH_DEFAULT)
    time_max: bpy.props.FloatProperty(name="時間の長さ (Y最大)", default=SINE_TIME_MAX_DEFAULT)
    
    time_t: bpy.props.FloatProperty(name="現在の時間 t", default=SINE_TIME_DEFAULT)
    wave_speed_x: bpy.props.FloatProperty(name="X方向速度 (v)", default=SINE_WAVE_SPEED_X_DEFAULT, soft_min=-10.0, soft_max=10.0)
    delay: bpy.props.FloatProperty(name="開始時間の遅れ", default=SINE_DELAY_DEFAULT)
    resolution: bpy.props.IntProperty(name="解像度", default=SINE_RESOLUTION_DEFAULT, min=2)
    
    init_show: bpy.props.BoolProperty(name="初期波 (t=0) を描画", default=True)
    init_thickness: bpy.props.FloatProperty(name="初期波の太さ", default=0.05, min=0.0)
    init_color: bpy.props.FloatVectorProperty(name="初期波の色", subtype='COLOR', size=4, default=INIT_COLOR, min=0.0, max=1.0)

    main_show: bpy.props.BoolProperty(name="時間波形 (現在の t) を描画", default=True)
    thickness: bpy.props.FloatProperty(name="時間波形の太さ", default=0.15, min=0.0)
    color_main: bpy.props.FloatVectorProperty(name="時間波形の色", subtype='COLOR', size=4, default=MAIN_COLOR, min=0.0, max=1.0)
    
    traj_show: bpy.props.BoolProperty(name="時間軌跡 (x=0) を描画", default=True)
    traj_thickness: bpy.props.FloatProperty(name="軌跡の太さ", default=0.1, min=0.0)
    traj_color: bpy.props.FloatVectorProperty(name="軌跡の色", subtype='COLOR', size=4, default=TRAJ_COLOR, min=0.0, max=1.0)

    tx_show: bpy.props.BoolProperty(name="t=x 波面を描画", default=True)
    tx_thickness: bpy.props.FloatProperty(name="t=x 波の太さ", default=0.12, min=0.0)
    tx_color: bpy.props.FloatVectorProperty(name="t=x 波の色", subtype='COLOR', size=4, default=TX_COLOR, min=0.0, max=1.0)

# ===================================
# オペレーター (生成処理)
# ===================================
class SINE_WAVE_OT_generate(bpy.types.Operator):
    bl_idname = f"{PREFIX}.generate"
    bl_label = "波と軌跡を生成"

    def create_curve_object(self, name, thickness, color, collection):
        curve_data = bpy.data.curves.new(name=name, type='CURVE')
        curve_data.dimensions = '3D'
        curve_data.bevel_depth = thickness
        curve_data.bevel_resolution = 4
        
        spline = curve_data.splines.new(type='POLY')
        
        obj = bpy.data.objects.new(name, curve_data)
        collection.objects.link(obj)
        
        mat = bpy.data.materials.new(name=f"{name}_Mat")
        mat.use_nodes = True
        mat.blend_method = 'BLEND'
        bsdf = mat.node_tree.nodes.get("Principled BSDF")
        if bsdf:
            bsdf.inputs['Base Color'].default_value = color
            if len(color) == 4 and color[3] < 1.0:
                bsdf.inputs['Alpha'].default_value = color[3]
        obj.data.materials.append(mat)
        
        return spline

    def execute(self, context):
        props = context.scene.sine_wave_props
        collection = context.collection

        # 1. 初期波形 (t=0)
        if props.init_show:
            spline_init = self.create_curve_object("Wave_Init_t0", props.init_thickness, props.init_color, collection)
            spline_init.points.add(props.resolution - 1)
            for i in range(props.resolution):
                x_local = (i / (props.resolution - 1)) * props.length
                y = 0.0 + SINE_LOC_Y_DEFAULT
                z = calculate_z_displacement(x_local, 0.0, props)
                spline_init.points[i].co = (x_local + SINE_LOC_X_DEFAULT, y, z, 1.0)

        # 2. メインの波 (現在の時間)
        if props.main_show:
            spline_main = self.create_curve_object(f"Wave_Main_t{props.time_t:.1f}", props.thickness, props.color_main, collection)
            spline_main.points.add(props.resolution - 1)
            for i in range(props.resolution):
                x_local = (i / (props.resolution - 1)) * props.length
                y = props.time_t + SINE_LOC_Y_DEFAULT
                z = calculate_z_displacement(x_local, props.time_t, props)
                spline_main.points[i].co = (x_local + SINE_LOC_X_DEFAULT, y, z, 1.0)

        # 3. 時間軌跡 (x=0)
        if props.traj_show and props.time_max > 0.0:
            spline_traj = self.create_curve_object("Trajectory_x0", props.traj_thickness, props.traj_color, collection)
            spline_traj.points.add(props.resolution - 1)
            for i in range(props.resolution):
                tau = (i / (props.resolution - 1)) * props.time_max
                x_local = 0.0
                y = tau + SINE_LOC_Y_DEFAULT
                z = calculate_z_displacement(x_local, tau, props)
                spline_traj.points[i].co = (x_local + SINE_LOC_X_DEFAULT, y, z, 1.0)

        # 4. t=x 波面
        if props.tx_show:
            spline_tx = self.create_curve_object("Wave_t_equals_x", props.tx_thickness, props.tx_color, collection)
            spline_tx.points.add(props.resolution - 1)
            for i in range(props.resolution):
                max_tx_length = min(props.length, props.time_max)
                x_local = (i / (props.resolution - 1)) * max_tx_length
                t_local = x_local
                y = t_local + SINE_LOC_Y_DEFAULT
                z = calculate_z_displacement(x_local, t_local, props)
                spline_tx.points[i].co = (x_local + SINE_LOC_X_DEFAULT, y, z, 1.0)

        return {'FINISHED'}

# ===================================
# UI パネル・登録処理
# ===================================
class SINE_WAVE_PT_panel(bpy.types.Panel):
    bl_label = ADDON_TITLE
    bl_idname = f"{PREFIX}_PT_panel"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = "SineWave"

    def draw(self, context):
        layout = self.layout
        props = context.scene.sine_wave_props

        box = layout.box()
        box.label(text="基本設定", icon='VIEW_ORTHO')
        box.prop(props, "amplitude")
        box.prop(props, "frequency")
        box.prop(props, "length")
        box.prop(props, "time_max")
        box.prop(props, "time_t")
        box.prop(props, "wave_speed_x")
        box.prop(props, "delay")
        box.prop(props, "resolution")
        
        box2 = layout.box()
        box2.label(text="波の描画設定", icon='OUTLINER_OB_CURVE')
        box2.prop(props, "init_show", icon='TIME')
        if props.init_show:
            row = box2.row()
            row.prop(props, "init_thickness", text="太さ")
            row.prop(props, "init_color", text="")

        box2.prop(props, "main_show", text=f"時間波形 (t={props.time_t:.1f})", icon='MOD_WAVE')
        if props.main_show:
            row = box2.row()
            row.prop(props, "thickness", text="太さ")
            row.prop(props, "color_main", text="")
            
        box2.prop(props, "traj_show", text=f"時間軌跡 (t=0〜{props.time_max:.0f})", icon='ANIM')
        if props.traj_show:
            row = box2.row()
            row.prop(props, "traj_thickness", text="太さ")
            row.prop(props, "traj_color", text="")

        box2.prop(props, "tx_show", icon='CON_TRANSLIKE')
        if props.tx_show:
            row = box2.row()
            row.prop(props, "tx_thickness", text="太さ")
            row.prop(props, "tx_color", text="")
        
        layout.separator()
        row = layout.row()
        row.scale_y = 1.5
        row.operator(SINE_WAVE_OT_generate.bl_idname, text="波と軌跡を作成", icon='PLAY')

def setup_viewport_ui():
    for window in bpy.context.window_manager.windows:
        for area in window.screen.areas:
            if area.type == 'VIEW_3D':
                for space in area.spaces:
                    if space.type == 'VIEW_3D':
                        space.shading.type = 'MATERIAL'
                        space.show_region_ui = True
    return None

classes = (SineWaveProperties, SINE_WAVE_OT_generate, SINE_WAVE_PT_panel)

def register():
    for cls in classes:
        bpy.utils.register_class(cls)
    bpy.types.Scene.sine_wave_props = bpy.props.PointerProperty(type=SineWaveProperties)
    bpy.app.timers.register(setup_viewport_ui, first_interval=0.1)

def unregister():
    for cls in reversed(classes):
        bpy.utils.unregister_class(cls)
    del bpy.types.Scene.sine_wave_props

if __name__ == "__main__":
    register()
時間軌跡をt=0kara10 egaite