えーあい

ハハハ
私がAI使ってるって言ったら、弟が爆笑する・・・
いや、わたしかて使うがな・・・って言ったら、
あんたがAIみたいな人やのになんでAIつことんねん
・・・なんやねんそれ・・・
という会話・・・でも、これ、他の人にも言われて、すごく複雑です

ということで、ChatGPTとGEMINIを使ってて、最近Claudeも使ってる感じ。
3D関係ははやりのHi3D、Hitem3Dとかいろいろ使ってる。
どれも、便利ですけど、PYTHONコード書くのにGEMINIとClaudeはすごいなって思います。
JWCADのPYTHON外変を書いていますけど、GEMINIに聞いたら、ほぼ完全な形で答えてくれて、「私 頭いらーん」ってなってます。

っていうか、ブラウザの検索のAI回答もすごいですよね・・・
ほんとにびっくりします。

あ、そうそう、スマホの写真画像のお花とかを検索してくれるの、めっちゃ便利。
知らないかわいいお花にスマホ向けたら教えてくれる。
ひとりでニヤニヤしてるの、かなり気持ち悪いと思うけど、ひとりぼっちだから仕方ないのさ…

GEMINIが作った、図面内の線を交点で分割するコードcircle_split.py(曲線属性とかは対象外)utf-8で保存だよ


import sys
import math
from itertools import combinations

# --- 1. 数学・幾何学計算の関数群 ---

def find_line_line_intersection(line1, line2):
    """直線と直線の交点を求める"""
    x1, y1, x2, y2 = line1
    x3, y3, x4, y4 = line2
    denominator = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4)
    if abs(denominator) < 1e-6:
        return None
    px = ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)) / denominator
    py = ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)) / denominator
    return px, py

def find_line_circle_intersections(line, circle):
    """直線と円の交点を求める"""
    lx1, ly1, lx2, ly2 = line
    cx, cy, cr = circle
    
    # 円の中心を原点 (0,0) に移動して考える
    x1, y1 = lx1 - cx, ly1 - cy
    x2, y2 = lx2 - cx, ly2 - cy
    
    dx, dy = x2 - x1, y2 - y1
    dr = math.sqrt(dx**2 + dy**2)
    D = x1 * y2 - x2 * y1
    
    # 判別式
    discriminant = (cr**2) * (dr**2) - D**2
    if discriminant < 0:
        return [] # 交点なし
        
    # 交点座標の計算(円の中心基準)
    sign_dy = 1 if dy >= 0 else -1
    sqrt_disc = math.sqrt(discriminant)
    
    pts = []
    # 交点1
    xa = (D * dy + sign_dy * dx * sqrt_disc) / (dr**2)
    ya = (-D * dx + abs(dy) * sqrt_disc) / (dr**2)
    pts.append((xa + cx, ya + cy))
    
    if discriminant > 1e-6:
        # 交点2(接していない場合)
        xb = (D * dy - sign_dy * dx * sqrt_disc) / (dr**2)
        yb = (-D * dx - abs(dy) * sqrt_disc) / (dr**2)
        pts.append((xb + cx, yb + cy))
        
    return pts

def find_circle_circle_intersections(circle1, circle2):
    """円と円の交点を求める"""
    cx1, cy1, cr1 = circle1
    cx2, cy2, cr2 = circle2
    
    # 中心点間の距離
    d = math.sqrt((cx2 - cx1)**2 + (cy2 - cy1)**2)
    
    # 交点を持たない条件のチェック
    if d > cr1 + cr2 or d < abs(cr1 - cr2) or d < 1e-6:
        return []
        
    # 交点を通る直線(根軸)へのアプローチ
    a = (cr1**2 - cr2**2 + d**2) / (2 * d)
    h = math.sqrt(max(0.0, cr1**2 - a**2))
    
    # 2つの円の中心を結ぶ直線上の点
    x2 = cx1 + a * (cx2 - cx1) / d
    y2 = cy1 + a * (cy2 - cy1) / d
    
    # 交点座標の算出
    rx = -h * (cy2 - cy1) / d
    ry = h * (cx2 - cx1) / d
    
    pts = [(x2 + rx, y2 + ry)]
    if h > 1e-6:
        pts.append((x2 - rx, y2 - ry))
        
    return pts

# --- 2. 判定・補助用関数群 ---

def is_point_on_segment(px, py, line, tol=1e-3):
    """点が線分の範囲内にあるか判定"""
    x1, y1, x2, y2 = line
    within_x = min(x1, x2) - tol <= px <= max(x1, x2) + tol
    within_y = min(y1, y2) - tol <= py <= max(y1, y2) + tol
    return within_x and within_y

def get_angle(cx, cy, px, py):
    """中心から見た点の角度(0~360度)"""
    return math.degrees(math.atan2(py - cy, px - cx)) % 360


# --- 3. メイン処理 ---

def main():
    if len(sys.argv) < 2:
        return
    temp_file = sys.argv[1]

    lines_data = []   # 各要素: [x1, y1, x2, y2]
    circles_data = [] # 各要素: [cx, cy, r]

    # --- Jw_cadデータの読み込み ---
    with open(temp_file, 'r', encoding='ms932') as f:
        for line in f:
            parts = line.split()
            if not parts:
                continue
            # 円データの抽出
            if parts[0] == 'ci' and len(parts) >= 4:
                try:
                    # 簡易化のため真円(扁平率1,傾き0)として読み込み
                    circles_data.append([float(parts[1]), float(parts[2]), float(parts[3])])
                except ValueError:
                    continue
            # 直線データの抽出
            elif len(parts) == 4:
                try:
                    lines_data.append([float(p) for p in parts])
                except ValueError:
                    continue

    # 収集する交点情報を格納する入れ物
    # {インデックス: [交点座標のリスト]}
    line_pts = {i: [] for i in range(len(lines_data))}
    circle_angles = {i: [] for i in range(len(circles_data))}

    # --- 交点の総当たり計算 ---
    
    # A. 直線 × 直線
    for (i, l1), (j, l2) in combinations(enumerate(lines_data), 2):
        pt = find_line_line_intersection(l1, l2)
        if pt and is_point_on_segment(pt[0], pt[1], l1) and is_point_on_segment(pt[0], pt[1], l2):
            line_pts[i].append(pt)
            line_pts[j].append(pt)

    # B. 直線 × 円
    for i, l in enumerate(lines_data):
        for j, c in enumerate(circles_data):
            pts = find_line_circle_intersections(l, c)
            for pt in pts:
                if is_point_on_segment(pt[0], pt[1], l):
                    line_pts[i].append(pt)
                    # 円側は角度に変換して記録
                    circle_angles[j].append(get_angle(c[0], c[1], pt[0], pt[1]))

    # C. 円 × 円
    for (i, c1), (j, c2) in combinations(enumerate(circles_data), 2):
        pts = find_circle_circle_intersections(c1, c2)
        for pt in pts:
            circle_angles[i].append(get_angle(c1[0], c1[1], pt[0], pt[1]))
            circle_angles[j].append(get_angle(c2[0], c2[1], pt[0], pt[1]))

    # --- 図形の再構築と書き出し ---
    
    output_commands = []

    # 1. 直線の分割
    for i, line in enumerate(lines_data):
        pts = list(set([(round(p[0], 4), round(p[1], 4)) for p in line_pts[i]])) # 重複排除
        x1, y1, x2, y2 = line
        if not pts:
            output_commands.append(f"{x1} {y1} {x2} {y2}\n")
            continue
        # 線の向きに合わせてソート
        if abs(x1 - x2) > abs(y1 - y2):
            pts_sorted = sorted(pts, key=lambda p: p[0], reverse=(x1 > x2))
        else:
            pts_sorted = sorted(pts, key=lambda p: p[1], reverse=(y1 > y2))
            
        curr = (x1, y1)
        for nxt in pts_sorted:
            if math.hypot(curr[0]-nxt[0], curr[1]-nxt[1]) > 1e-3:
                output_commands.append(f"{curr[0]} {curr[1]} {nxt[0]} {nxt[1]}\n")
            curr = nxt
        if math.hypot(curr[0]-x2, curr[1]-y2) > 1e-3:
            output_commands.append(f"{curr[0]} {curr[1]} {x2} {y2}\n")

    # 2. 円の分割
    for i, circle in enumerate(circles_data):
        cx, cy, cr = circle
        angles = list(set([round(a, 4) % 360 for a in circle_angles[i]])) # 重複排除
        if not angles:
            output_commands.append(f"ci {cx} {cy} {cr}\n")
            continue
            
        angles_sorted = sorted(angles)
        for j in range(len(angles_sorted)):
            p1 = angles_sorted[j]
            p2 = angles_sorted[(j + 1) % len(angles_sorted)]
            # 円弧コマンドとして出力 (扁平率1, 傾き0)
            output_commands.append(f"ci {cx} {cy} {cr} {p1} {p2} 1 0\n")

    # --- Jw_cadへ結果を上書き書き込み ---
    with open(temp_file, 'w', encoding='ms932') as f:
        f.write("hd\n") # 元の選択図形を削除
        f.writelines(output_commands)

if __name__ == '__main__':
    main()

バッチファイルはcircle_split.bat こっちはshift-jisで保存だよ


@REM 円と直線・円と円の交点切断
@echo off
REM #jww
REM #cd
REM #h1 範囲選択で円や直線を選んでください
REM #e
python.exe circle_split.py jwc_temp.txt

# 私の場合はこの前後にjwc_temp.txtをエディタで表示させるコマンドとPAUSEのコマンドが挟まっていますけど・・・

こんな感じで、まるまるコピペで使えてしまいます…

※申し訳ないのですが、このコードはGEMINI(生成AI)が作成したコードです。つまりもとになっているコードが存在するかもしれません。基本的には、交点計算やJWW特有の円弧の計算、表記方法などがあるのですが、どなたかの著作物と競合しているようでしたら、本文から削除いたしますので、このページのコメント欄にご記入ください。
ご記載をお願いしたい内容:対象署の方へ連絡できるサイト名と著作権者の方のお名前、著作権が発生しているコードのコード名(スクリプト名)、と、ご連絡頂いた方のご連絡先(ホームページや掲示板など)とお名前。
お手数ですが、よろしくお願い申し上げます。

また、JWCAD(JWW)の外部変形機能では、
Windows11の方は、ターミナルの設定?やったかしら・・・から、「既定のターミナルアプリケーション」の項目を「Windows ターミナル」から「Windows コンソール ホスト」に変更しましょうね…

確かこんなことしたような気がします。そうすると、Windows10までの感じ以上に早く動きます。まあ、これはパソコンの性能にもよるのかなって思いますけど、遅いってことはなくなるはず・・・。私の場合は、Pythonでもかなり早いです。