金曜日, 6月 19, 2026

JavaScriptでAI遊び 96 
Illustratorでオブジェクトのアンカーポイントを均一に(2)

以前作成したバージョンの曲線対応版です。

main();

function main() {

if (app.documents.length == 0) {
alert("ドキュメントを開いてください");
return;
}

var doc = app.activeDocument;

if (doc.selection.length == 0) {
alert("パスを選択してください");
return;
}

var path = doc.selection[0];

if (!(path instanceof PathItem)) {
alert("PathItemを選択してください");
return;
}

var targetCount = Number(
prompt("アンカーポイント数", 30)
);

if (targetCount < 2) {
return;
}

var samples = buildSamples(path, 20);

var totalLength =
samples[samples.length - 1].dist;

var newPts = [];

for (var i = 0; i < targetCount; i++) {

var tdist;

if (path.closed) {
tdist =
totalLength * (i / targetCount);
} else {
tdist =
totalLength *
(i / (targetCount - 1));
}

newPts.push(
getPointAtDistance(samples, tdist)
);
}

createSmoothPath(doc, newPts, path.closed);

alert("完了");
}

// サンプル生成
function buildSamples(path, divs) {

var pts = path.pathPoints;

var result = [];

var accum = 0;

for (var i = 0; i < pts.length; i++) {

var next;

if (i == pts.length - 1) {

if (!path.closed) break;

next = 0;

} else {

next = i + 1;
}

var p0 = pts[i].anchor;
var p1 = pts[i].rightDirection;
var p2 = pts[next].leftDirection;
var p3 = pts[next].anchor;

var prev = null;

for (var j = 0; j <= divs; j++) {

var t = j / divs;

var p = cubicBezier(
p0, p1, p2, p3, t
);

if (prev) {
accum += distance(prev, p);
}

result.push({
pt: p,
dist: accum
});

prev = p;
}
}

return result;
}

// ベジェ評価
function cubicBezier(p0,p1,p2,p3,t){

var mt = 1 - t;

var x =
mt*mt*mt*p0[0] + 3*mt*mt*t*p1[0] + 3*mt*t*t*p2[0] +
t*t*t*p3[0];

var y =
mt*mt*mt*p0[1] + 3*mt*mt*t*p1[1] + 3*mt*t*t*p2[1] +
t*t*t*p3[1];

return [x,y];
}

// 距離
function distance(a,b){

var dx = b[0]-a[0];
var dy = b[1]-a[1];

return Math.sqrt(dx*dx+dy*dy);
}

// 距離位置取得
function getPointAtDistance(samples, d){

for (var i=1; i<samples.length; i++){

if (samples[i].dist >= d){

var prev = samples[i-1];
var curr = samples[i];

var span =
curr.dist - prev.dist;

var ratio =
(d - prev.dist) / span;

var x =
prev.pt[0] + (curr.pt[0]-prev.pt[0])*ratio;

var y =
prev.pt[1] + (curr.pt[1]-prev.pt[1])*ratio;

return [x,y];
}
}

return samples[samples.length-1].pt;
}

// 新規スムーズパス生成
function createSmoothPath(doc, pts, closed){

var p = doc.pathItems.add();

p.setEntirePath(pts);

p.closed = closed;

p.stroked = true;
p.filled = false;

var pp = p.pathPoints;

for (var i=0; i<pp.length; i++){

pp[i].pointType = PointType.SMOOTH;

var prev =
pts[(i-1+pts.length)%pts.length];

var next =
pts[(i+1)%pts.length];

var dx = (next[0]-prev[0]) * 0.18;
var dy = (next[1]-prev[1]) * 0.18;

pp[i].leftDirection = [
pts[i][0]-dx,
pts[i][1]-dy
];

pp[i].rightDirection = [
pts[i][0]+dx,
pts[i][1]+dy
];
}
}
調整したいオブジェクトを選択して実行すると・・・

アンカーポイント数を指定します。デフォルトは30です。

問題なく処理が完了すると・・・
オリジナルの上にポイントが追加され、オリジナルを選択している状態なので削除またはロックします。
ポイントを60にした結果。
 










ちなみに極端に少ないポイント数を指定すると形状は崩れます。

TCDW8802 
誰も気にしていないのが、ちょっと不気味

先日、地下鉄の構内で突風に遭遇しました。意味不明です。よく利用する通路ですが、こんな体験は初めてでした。誰も気にしていないのが、ちょっと不気味。

木曜日, 6月 18, 2026

Let's start JavaScript 103 
指定したpixelとppi時のmm(cm)を計算

指定したpixelとppi時のmm(cm)を計算します。
処理画像や撮影した写真を指定解像度で利用した時のサイズ(mm/cm)を計算します。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>画像サイズ計算</title>
<style>
body {
background: black;
color: white;
}

input {
width: 80px;
margin: 5px;
}
</style>

</head>
<body>
<center>
<h3>画像サイズ計算</h3>

<label>
幅/width (pixel):
<input id="widthPx" type="number" value="6000">
</label>
<br>

<label>
高さ/height (pixel):
<input id="heightPx" type="number" value="4000">
</label>
<br>

<label>
解像度/resolution (ppi):
<input id="dpi" type="number" value="350">
</label>
<br><br>

<button onclick="calc()">計算</button>

<div id="result"></div>

<script>
function calc() {
const widthPx =
    Number(document.getElementById("widthPx").value);
const heightPx =
    Number(document.getElementById("heightPx").value);
const dpi = Number(document.getElementById("dpi").value);

if (dpi <= 0) {
document.getElementById("result").textContent =
"DPIは0より大きい値を入力してください";
return;
}

const widthMm = widthPx / dpi * 25.4;
const heightMm = heightPx / dpi * 25.4;

document.getElementById("result").innerHTML = `
<p>幅/width: ${widthMm.toFixed(1)} mm
        (${(widthMm/10).toFixed(1)} cm)<br>
高さ/height: ${heightMm.toFixed(1)} mm
        (${(heightMm/10).toFixed(1)} cm)</p>
`;
}
</script>
</center>
</body>
</html>

実行直後の状態。必要事項を入力して[計算]をクリックするだけで・・・

結果が表示されます。

TCDW8801 
似たようなモノが多すぎるのが問題ですね

Cute Baby Alien 042(^o^)
サイネズミ系・・・(^o^)
いつもの様に左手でエアコンのスイッチを入れたら反応しないので、手元を見たらリモコンではなくて電卓でした(^o^)汗・・・疲れているのかも。似たようなモノが多すぎるのが問題ですね。いや、目視してない私がアホでした。
 

水曜日, 6月 17, 2026

Blender Study Notes 74 
テキストのメッシュ状態を方眼に変更

テキストのメッシュ状態を方眼に変更する手順と後処理について纏めてみました。

Illustratorでアウトライン化しSVGで書き出したデータをBlenderに配置し全体の結合と表示カラーをデフォルトに変更します。ここで[オブジェクトモード]でデータを選択し、右クリックで[変換]>[メッシュ]として・・・

※SVGデータを配置して全体の結合と表示カラーをデフォルトに変更する手順は以下を参照してください。
Blender Study Notes 72 <br>Illustratorから テキストデータを 活用時の注意点 2026/05/19

[編集モード]に切り換えると絶望的なメッシュ状態を確認出来ます。これを方眼に変更するには・・・

まず、右クリックで[変換]>[メッシュ]は行わず、[オブジェクトモード]にてデータを少し上に移動させます。

次に[追加]>[メッシュ]>[平面]で平面メッシュを作成し・・・

文字データに合わせてサイズ調整します。

ここで[編集モード]にきりかえ、底面データを選択し右クリックで[細分化]を選び・・・

左下に表示されるパレットで[分割数]を任意設定します。あまり粗い分割数にすると結果が煩雑になるので気持ち細か目がベストです。

分割が完了したら[オブジェクトモード]に切り換え、文字を選択後にShiftキーえを併用して平面も選択します。

ここで[編集モード]に切り換え[メッシュ]>[ナイフ投影]を選ぶと・・・

平面の中から文字データと同じサイズの面取りされたデータを選択された状態になるので・・・


Shift Dを押したまま移動し、Pキーで[分離]>[選択]を実行し、平面とベーストス日田文字データー非表示、または削除します。

これでメッシュ状態を方眼に変更出来ます。ただし、場合により細部が崩れることがあります。

ただし、輪郭部分に余計なポイントがあるので調整したいのですが、SVGで」配置したデータの場合は輪郭のポイントの全選択出来る[option ダブルクリック](※)が何故か機能しないので頓挫してしまいましたが、使用のようでテキストデータで処理すれば可能だと判明しました。

※Windowsの場合は[alt ダブルクリック]

[追加]>[テキスト]では日本語入力が出来ませんが、コピー&ペーストで入力できます。

入力後の処理は同じでメッシュ状態を方眼に変更したら輪郭のポイントを[option ダブルクリック](※)で選択し[X]>[限定的溶解]を実行すれば・・・

※Windowsの場合は[alt ダブルクリック]

余凡なポイントをある程度調整することが出来ます。漢字の場合は首部毎にこれを行います

Blender 5.1.0

TCDW8800 
焦っても何も解決しませんが・・・

昨夜の地震は久しぶりに緊張しました。被害はありませんでしたが揺れ方がキモイと焦りますね。まっ、焦っても何も解決しませんが・・・風呂から出た直後だったのでちょっと焦りました。

火曜日, 6月 16, 2026

Photoshopでαチャンネルの加算減算

質問がありましたので・・・
Photoshopでαチャンネル作成と、その加算減算について整理しました。

用意した画像です。パプリカをマスキングします。ただし、写真の様にテーブル付近が暗い場合は選択処理に誤差が出るので・・・


レイヤーの複製を作成し、さらに新規レーヤーを作成して・・・

そのレイヤーをグラデーションで塗りつぶします。

ここでチャンネルに移動し、任意のチャンネルサムネールをcommnad(※)キーを併用してクリックして選択範囲とし・・・

※Windowsはcontrol

[ウィンドウ]>[色調補正]>[色相・彩度]をクリックすると・・・

作成したグラデーションを反映させた[色相・彩度]のレイヤーがセ永逝されます。

ここで暗い部分を認識しやすいように適宜調整します。

処理後に2つのレイヤーを選択し[レイヤーオプション]>[レイヤーを結合]し・・・

暗部が確認しやすい画像を得て、そのレイヤーに対して[選択範囲]>[被写体を選択]または、[ツールバー]>[オブジェクト選択]にてパプリカを矩形選択するなどして選択範囲を得ます。

微修正は,選択範囲を得てからブラシで調整します。

選択範囲を修正したら・・・

チャンネルに移動し[オプション]>[新規αチャンネル]で新規αチャンネルを作成し・・・

作成したαチャンネルを選択し・・・

背景色が白である事を確認し・・・

[delate]キーでカットします。

処理が完了したら、表示をオフにし・・・

RGBをクリックして通常状態に戻します。

続けて[ツールバー]>[オブジェクト選択]にて黄色いパプリカを矩形選択して・・・

選択範囲を得ます。

そのままチャンネルにαチャンネルを新たに作成します。ここで赤いパプリカだけのチャンネルを簡単に作成することができます。

αチャンネル1をcommand(※)でクリックし・・・
αチャンネル2をoption command(※)でクリックすると、αチャンネル1からαチャンネル2を差し引いた選択範囲が出来ます。そのままαチャンネル3を作成します。

※command(Windowsはcontrol)
 control(Windowsはalt)

αチャンネル2をcommand(※)でクリックし・・・
αチャンネル3をshift command(※)でクリックすると、αチャンネル2αチャンネル3を加算した選択範囲が得られます。

※command(Windowsはcontrol)

このマスクの加算減算は、αチャンネル、レイヤーマスク、パス、レイヤー(※)の間でも処理出来ます。それぞれの場所でのクリックです。

※レイヤーは透明部分以外が選択されます。