2022年11月20日日曜日

p5jsの透過処理バグ回避のシェーダーの設定

2022 11/20の時点でこのバグはまだ健在

https://discourse.processing.org/t/webgl-alpha-cant-be-used-as-a-texture/35981

の解決案のソースを参考にシェーダーの今回使わないライト設定を削り

createShader()したらバグが消えたようなので残しておく

シェーダーの必要な部分も消えてるかもしれないので挙動が怪しい場合は

上記記事から加工前のシェーダーを引っ張って来て使おう



<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.js"></script>
<div id="p5canvas"></div>
<script>
	//Reference site
	//https://discourse.processing.org/t/webgl-alpha-cant-be-used-as-a-texture/35981

	let img;
	let buf;
	let shdr;
	let spritedata = '00101032323255bb30b27134f8300d0000400000014000000140000001500000105000005d55000115410000d51d4011415444055d5c5405455510011555400002800000028000000a8000002aa800';

	let camerax = 0;
	let cameray = 90;
	let cameraz = -300;
	let lookatx = 0;
	let lookatz = 0;

	let trees = [
		[0, 0, 200],
		[-200, 0, 200],
		[200, 0, 20]
	]

	//makeimage from hex strings with magnifi (1,2,4,8,16)
	function makeimage(hexstrings, magni) {
		let ix = hexstrings;
		//read header  "transparent num","imagew","imageh" [0~6] (3byte)
		let tpc = parseInt(ix.slice(0, 2), 16);
		let imgw = parseInt(ix.slice(2, 4), 16);
		let imgh = parseInt(ix.slice(4, 6), 16);
		let imagemap = [];
		//read color palet "palet rgb(3yite)"x3 [6~30] (24 = 12byte = 4x3)
		let colorpalet = [];
		for (let i = 0; i < 4; i++) {
			let rgba = [];
			for (let j = 0; j < 3; j++) {
				rgba.push(parseInt(
					//head + rgb(3byte)+r(1byte)+g(1byte)+b(1byte) (1byte=2char)
					ix.slice(6 + i * 6 + j * 2, 8 + i * 6 + j * 2), 16));
			}
			if (tpc == i) {
				rgba.push(0);
			} else {
				rgba.push(255);
			}
			colorpalet.push(rgba);
		}
		//read pixels color one pixel 4 bit   [30~EOF] (4bit *2 =1byte=2pixels)
		for (let i = 30; i < ix.length; i++) {
			let onebyte = parseInt(ix[i], 16);
			let upper = parseInt(onebyte / 4);
			let lower = onebyte % 4;
			imagemap.push(upper);
			imagemap.push(lower);
		}
		let himg = createImage(imgw * magni, imgh * magni);
		himg.loadPixels();

		for (let y = 0; y < himg.height; y++) { ///magnifi; y++) {
			for (let x = 0; x < himg.width; x++) { ///magnifi; x++) {
				let index = (x + y * himg.width) * 4;
				let cnum = imagemap[
					parseInt(x / magni) +
					parseInt(y / magni) * imgw];

				himg.pixels[index] = colorpalet[cnum][0];
				himg.pixels[index + 1] = colorpalet[cnum][1];
				himg.pixels[index + 2] = colorpalet[cnum][2];
				himg.pixels[index + 3] = colorpalet[cnum][3];
			}
		}
		himg.updatePixels();
		return himg;
	}
	//camera turn
	function mouseDragged() {
		lookatx += (pmouseX - mouseX) * 0.01;
		lookatz += (pmouseY - mouseY) * 0.01;
		if (lookatx > TWO_PI) lookatx -= TWO_PI; //loop
		if (lookatx < 0) lookatx += TWO_PI;
		if (lookatz > PI + QUARTER_PI) lookatz = PI + QUARTER_PI; //no loop
		if (lookatz < PI - QUARTER_PI) lookatz = PI - QUARTER_PI;
	}
	// camera move
	function keyinput() {
		let zx = cos(lookatx) * 5;
		let zz = sin(lookatx) * 5;
		if (keyIsDown(87)) { //w
			camerax += zx;
			cameraz += zz;
		} else
		if (keyIsDown(83)) { //s
			camerax -= zx;
			cameraz -= zz;
		}
		zx = cos(lookatx + HALF_PI) * 5;
		zz = sin(lookatx + HALF_PI) * 5;
		if (keyIsDown(65)) { //a
			camerax -= zx;
			cameraz -= zz;
		} else
		if (keyIsDown(68)) { //d
			camerax += zx;
			cameraz += zz;
		}
	}

	function setup() {
		img = makeimage(spritedata, 16);
		lookatz = 3.5; // PI;
		lookatx = 1.6; // HALF_PI;

		createCanvas(700, 400, WEBGL).parent("p5canvas");
		shdr = createShader(vert, frag);
		shader(shdr);
		noStroke();
	}


	function draw() {
		background(150, 150, 255);
		keyinput();
		shdr.setUniform('mydiffuse', sin(frameCount * 0.01));
		camera(camerax, cameray, cameraz,
			(cos(lookatx) * -cos(lookatz)) + camerax,
			sin(lookatz) + cameray,
			sin(lookatx) + cameraz, 0.0, 1.0, 0.0);

		for (let [x, y, z] of trees) {
			push();
			translate(x, y, z);
			rotateY(QUARTER_PI);
			texture(img);
			plane(255);
			rotateY(HALF_PI);
			plane(255);
			pop();
		}

		push();
		fill(0, 255, 0);
		translate(0, 127, 0);
		rotateX(HALF_PI);
		plane(1000);
		pop();

		push();
		translate(0, 0, 0);
		rotateY(frameCount * 0.01);
		texture(img);
		plane(255);
		rotateY(HALF_PI);
		plane(255);
		pop();
	}


	let vert = `
		precision highp float;
		precision highp int;

		uniform bool uUseLighting;
		uniform float mydiffuse;

		void totalLight(
		  vec3 modelPosition,
		  vec3 normal,
		  out vec3 totalDiffuse,
		  out vec3 totalSpecular
		) {
		  totalSpecular = vec3(0.0);
		  if (!uUseLighting) {
		    totalDiffuse = vec3(mydiffuse);
		    return;
		  }
		  totalDiffuse = vec3(0.0);
		  vec3 viewDirection = normalize(-modelPosition);
		}

		attribute vec3 aPosition;
		attribute vec3 aNormal;
		attribute vec2 aTexCoord;

		uniform mat4 uModelViewMatrix;
		uniform mat4 uProjectionMatrix;
		uniform mat3 uNormalMatrix;

		varying highp vec2 vVertTexCoord;
		varying vec3 vDiffuseColor;
		varying vec3 vSpecularColor;

		void main(void) {
		  vec4 viewModelPosition = uModelViewMatrix * vec4(aPosition, 1.0);
		  gl_Position = uProjectionMatrix * viewModelPosition;

		  vec3 vertexNormal = normalize(uNormalMatrix * aNormal);
		  vVertTexCoord = aTexCoord;

		  totalLight(viewModelPosition.xyz, vertexNormal, vDiffuseColor, vSpecularColor);
		}`;
	let frag = `
		precision highp float;

		uniform vec4 uMaterialColor;
		uniform vec4 uTint;
		uniform sampler2D uSampler;
		uniform bool isTexture;
		uniform bool uEmissive;

		varying highp vec2 vVertTexCoord;
		varying vec3 vDiffuseColor;
		varying vec3 vSpecularColor;

		void main(void) {
		  if(uEmissive && !isTexture) {
		    gl_FragColor = uMaterialColor;
		  }
		  else {
		    gl_FragColor = isTexture ? texture2D(uSampler, vVertTexCoord) * (uTint / vec4(255, 255, 255, 255)) : uMaterialColor;
		    gl_FragColor.rgb = gl_FragColor.rgb * vDiffuseColor + vSpecularColor;
		  }

		  if (gl_FragColor.a == 0.0) {
		    discard;
		  }
		}`;
</script>

image 拡大問題は解決したが透過処理のバグが出てくるp5js

Base64文字列からimageを作る ... ○
image で拡大して表示    ... △ めっちゃぼやける
    pixelを読み込んで拡大imageを作る .... ×
        Base64で読み込むのがOUTぽい

自前フォーマットでimageを作る ...○
pixelを読み込んで拡大imgを作る... ○
WebGL の3D のPLANEのテクスチャに設定...○
    テクスチャの透過処理... ×

2022 11/20時点でデフォルトのシェーダーだとこうなる
この一文が在るので https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.js
ここはこのまま、
次の投稿はこの問題の解決案

1pixel 4bit color のimage のデータを文字列で出力するエディタをp5jsでつくった


Base64で読み込んだimageで.loadPixels()を呼ぶとエラーがでるので

(2022 11/20現在)自前のフォーマットでimageデータ文字列を作ることに

したのでそれ用の簡易エディタを残しておく

作った文字列は下記の関数でimageに変換できる

引数は独自フォーマットの16進数文字列と拡大したい倍率

戻り値はimage

let myimage=makeimage(hexstrings,

で動くはず

上部

左からcanvas,色選択用のrect,カラーピッカー,透過パレットチェックボックス

中部

”magnifi select”(倍率)これはエディタでのみでデータにはならない

”outputsize” 出力画像サイズこれで倍率を選ぶと下部のtextareaに

データが出力される

下部

”output hex” 16進数 画像データ文字列, これをコピペして使う

”canvas crear ”canvasをクリアする

”input hex hera” ここに再編集したい文字列データを貼り付け

hex read をクリックするとcanvasに読み込み

1pixel 3色(透過の有り)か4色が使える(透過なし)

もしかしたらtextarea とかcolorpickerの表示位置が

ずれてるかもしれないが致し方なし。


//makeimage from hex strings with magnifi (1,2,4,8,16)
	function makeimage(hexstrings, magni) {
		let ix = hexstrings;
		//read header  "transparent num","imagew","imageh" [0~6] (3byte)
		let tpc = parseInt(ix.slice(0, 2), 16);
		let imgw = parseInt(ix.slice(2, 4), 16);
		let imgh = parseInt(ix.slice(4, 6), 16);
		let imagemap = [];
		//read color palet "palet rgb(3yite)"x4 [6~30] (24 = 12byte = 4x3)
		let colorpalet = [];
		for (let i = 0; i < 4; i++) {
			let rgba = [];
			for (let j = 0; j < 3; j++) {
				rgba.push(parseInt(
					//head + rgb(3byte)+r(1byte)+g(1byte)+b(1byte) (1byte=2char)
					ix.slice(6 + i * 6 + j * 2, 8 + i * 6 + j * 2), 16));
			}
			if (tpc == i) {
				rgba.push(0);
			} else {
				rgba.push(255);
			}
			colorpalet.push(rgba);
		}
		//read pixels color one pixel 4 bit   [30~EOF] (4bit *2 =1byte=2pixels)
		for (let i = 30; i < ix.length; i++) {
			let onebyte = parseInt(ix[i], 16);
			let upper = parseInt(onebyte / 4);
			let lower = onebyte % 4;
			imagemap.push(upper);
			imagemap.push(lower);
		}
		let himg = createImage(imgw * magni, imgh * magni);
		himg.loadPixels();

		for (let y = 0; y < himg.height; y++) { ///magnifi; y++) {
			for (let x = 0; x < himg.width; x++) { ///magnifi; x++) {
				let index = (x + y * himg.width) * 4;
				let cnum = imagemap[
					parseInt(x / magni) +
					parseInt(y / magni) * imgw];

				himg.pixels[index] = colorpalet[cnum][0];
				himg.pixels[index + 1] = colorpalet[cnum][1];
				himg.pixels[index + 2] = colorpalet[cnum][2];
				himg.pixels[index + 3] = colorpalet[cnum][3];
			}
		}
		himg.updatePixels();
		return himg;
	}

2022年11月16日水曜日

p5js 3d でFPSっぽいキー入力とマウス入力

いつぞやのコードが見つかったのでこちらに残す

3dでのキーとマウス入力


”A,S,D,F"で移動、マウスドラッグで方向転換



<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.js"></script>
<div id="p5canvas"></div>
<script>
	let camerax = 0;
	let cameray = 700;
	let cameraz = -350;
	let lookatx = 0;
	let lookatz = 0;

	function setup() {
		createCanvas(700, 400, WEBGL).parent("p5canvas");
		lookatz = 3.5; // PI;
		lookatx = 1.6; // HALF_PI;
	}
	//camera turn
	function mouseDragged() {
		lookatx += (pmouseX - mouseX) * 0.01;
		lookatz += (pmouseY - mouseY) * 0.01;
		if (lookatx > TWO_PI) lookatx -= TWO_PI; //loop
		if (lookatx < 0) lookatx += TWO_PI;
		if (lookatz > PI + QUARTER_PI) lookatz = PI + QUARTER_PI; //no loop
		if (lookatz < PI - QUARTER_PI) lookatz = PI - QUARTER_PI;
	}

	// camera move
	function keyinput() {
		let zx = cos(lookatx) * 5;
		let zz = sin(lookatx) * 5;
		if (keyIsDown(87)) { //w
			camerax += zx;
			cameraz += zz;
		}else
		if (keyIsDown(83)) { //s
			camerax -= zx;
			cameraz -= zz;
		}
		zx = cos(lookatx + HALF_PI) * 5;
		zz = sin(lookatx + HALF_PI) * 5;
		if (keyIsDown(65)) { //a
			camerax -= zx;
			cameraz -= zz;
		}else
		if (keyIsDown(68)) { //d
			camerax += zx;
			cameraz += zz;
		}
	}

	function draw() {
		background(250);
		camera(camerax, cameray, cameraz,
			(cos(lookatx) * -cos(lookatz)) + camerax,
			sin(lookatz) + cameray,
			sin(lookatx) + cameraz, 0.0, 1.0, 0.0); //
		keyinput();
		noStroke();
		normalMaterial();
		//ambientMaterial(255,255,255);
		//directionalLight(255,255,255, 0, 1, 0);
		push();
		translate(0, 0, 800);
		plane(1600);
		translate(0, 0, -1600);
		plane(1600);
		translate(0, 800, 800);
		rotateX(PI / 2);
		plane(1600);
		pop();

		beginShape(); // 閉矩形
		vertex(100, 0, -500);
		vertex(100, 100, -500);
		vertex(0, 100, -500);
		endShape(CLOSE);

		translate(-240, 400, 0);

		push();
		rotateZ(frameCount * 0.01);
		rotateX(frameCount * 0.01);
		rotateY(frameCount * 0.01);
		plane(70);
		pop();

		translate(240, 0, 0);
		push();
		rotateZ(frameCount * 0.01);
		rotateX(frameCount * 0.01);
		rotateY(frameCount * 0.01);
		box(70, 70, 70);
		pop();

		translate(240, 0, 0);
		push();
		rotateZ(frameCount * 0.01);
		rotateX(frameCount * 0.01);
		rotateY(frameCount * 0.01);
		cylinder(70, 70);
		pop();

		translate(-240 * 2, 200, 0);
		push();
		rotateZ(frameCount * 0.01);
		rotateX(frameCount * 0.01);
		rotateY(frameCount * 0.01);
		cone(70, 70);
		pop();

		translate(240, 0, 0);
		push();
		rotateZ(frameCount * 0.01);
		rotateX(frameCount * 0.01);
		rotateY(frameCount * 0.01);
		torus(70, 20);
		pop();

		translate(240, 0, 0);
		push();
		rotateZ(frameCount * 0.01);
		rotateX(frameCount * 0.01);
		rotateY(frameCount * 0.01);
		sphere(70);
		pop();
	}
</script>

2022年11月8日火曜日

迷路作成アルゴリズム p5jsで作る ループ有り

 ループ有りの迷路が作れたので残しておく

ゲームだと背後に回り込むとかできるので

使えそう



<!DOCTYPE html>
<html lang="en">
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.js"></script>
<div id="p5canvas"></div>

<script>
	class mymaze {
		writex = 0;
		writey = 0;
		msize = 0;
		state = 0;
		possiblesize = 0;
		maze = [];
		xtable = [2, -2, 0, 0];
		ytable = [0, 0, 2, -2];
		constructor(n) {
			this.msize = n;
		}


		mazeloop() {
			switch (this.state) {
				//pass through candidate points
				case 0:
					this.writex += 2;
					if (this.writex > this.msize - 2) {
						this.writex = 2;
						this.writey += 2;
					}
					if (this.writey > this.msize - 2)
						this.writey = 2;

					if (this.maze[this.writey][this.writex] == 0) {
						this.maze[this.writey][this.writex] = 2;
						this.possiblesize--;

						this.state = 1;
					}
					break;


				case 1:
					let direction = parseInt(Math.random() * 4);
					let addx = this.xtable[direction];
					let addy = this.ytable[direction];
					switch (this.maze[this.writey + addy][this.writex + addx]) {
						case 0:
							this.possiblesize--;
							this.maze[this.writey + addy][this.writex + addx] = 2;
							this.maze[this.writey + addy / 2][this.writex + addx / 2] = 2;
							this.writex += addx;
							this.writey += addy;
							break;
						case 1:
							this.maze[this.writey + addy / 2][this.writex + addx / 2] = 2;
							this.state = 2;
							break;
						case 2:
							this.state = 2;
							break;
					}
					break;

				case 2:
					for (let i = 1; i < this.msize - 1; i++) {
						for (let j = 1; j < this.msize - 1; j++) {
							if (this.maze[i][j] == 2)
								this.maze[i][j] = 1;
						}
					}
					this.state = 0;
					if (this.possiblesize <= 0)
						this.state = 4;
					break;
				case 4:
					this.writex = 1;
					this.writey = 1;
					break;
			}
		}

		mazeinit() {
			this.state = 0;
			let row = [];
			for (let i = 0; i < this.msize; i++) {
				row = [];
				for (let j = 0; j < this.msize; j++) {
					if (i == 0 || i == this.msize - 1 || j == 0 || j == this.msize - 1)
						row.push(1);
					else
						row.push(0);
				}
				this.maze.push(row);
			}
			this.writex = 2;
			this.writey = 2;
			//'n*2-1'=insid width ;'n*2'=block and space;'-1'=del extra space;'4'=(side block and space)*2
			this.possiblesize = (this.msize - 3) / 2; //n*2-1+4=maze_width ->  n=(maze_width-3)/2;
			this.possiblesize *= this.possiblesize;
		}
	}

	let mazesize = 21; //maze width height ,it must odd number
	let maze;

	function setup() {
		createCanvas(500, 500).parent("p5canvas");
		textSize(17);
		noStroke();

		maze = new mymaze(mazesize);
		maze.mazeinit();
	}

	function mousePressed() {
		maze = [];
		maze = new mymaze(mazesize);
		maze.mazeinit();
	}

	function draw() {
		background(100);
		let tilesize = parseInt(500 / (mazesize + 4));
		translate(tilesize * 2, tilesize * 2);
		maze.mazeloop();
		fill(255);
		for (let i = 0; i < maze.msize; i++)
			for (let j = 0; j < maze.msize; j++) {
				if (maze.maze[i][j] == 1) {
					fill(200);
					rect(j * tilesize, i * tilesize, tilesize - 2);
				} else if (maze.maze[i][j] == 2) {
					fill(100, 200, 100);
					rect(j * tilesize, i * tilesize, tilesize - 2);
				}
				if (maze.writex == j && maze.writey == i) {
					fill(255);
					rect(j * tilesize, i * tilesize, tilesize - 2);
				}
			}
		translate(-tilesize * 2, -tilesize * 2);
	}
</script>
</html>

2022年11月7日月曜日

クラスカル法

chat-gptにきいたらおしえてくれた

                                                   参考動画



<!DOCTYPE html>
<html lang="en">
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.js"></script>
<div id="p5canvas"></div>

<script>

class Graph {
  constructor() {
    this.vertices = [];
    this.edges = [];
  }

  addVertex(x, y) {
    this.vertices.push({ x, y });
  }

  addEdge(source, destination, weight) {
    if (this.vertices[source] && this.vertices[destination]) {
      this.edges.push({ source, destination, weight });
    } else {
      throw new Error("Invalid vertex");
    }
  }

  find(parents, vertex) {
    if (parents[vertex] === -1) {
      return vertex;
    }
    return this.find(parents, parents[vertex]);
  }

  union(parents, x, y) {
    const xRoot = this.find(parents, x);
    const yRoot = this.find(parents, y);
    parents[xRoot] = yRoot;
  }

 
  kruskalWithSteps() {
    const mst = [];
    const parents = Array(this.vertices.length).fill(-1);

    this.edges.sort((a, b) => a.weight - b.weight);

    for (let i = 0; i < this.edges.length; i++) {
    
  console.log("step",i);
      const { source, destination, weight } = this.edges[i];
      const sourceRoot = this.find(parents, source);
      const destinationRoot = this.find(parents, destination);

      if (sourceRoot !== destinationRoot) {
        mst.push({ source, destination, weight });
        this.union(parents, sourceRoot, destinationRoot);
      }
      
            console.log("Step:", i + 1);
      console.log("Minimum Spanning Tree:", mst);
      console.log("====================");
    }

    return mst;
  }


   findSingletonVertices(mstEdges,start,goal) {
    const vertexCount = new Map();

    for (const edge of mstEdges) {
      vertexCount.set(edge.source, (vertexCount.get(edge.source) || 0) + 1);
      vertexCount.set(edge.destination, (vertexCount.get(edge.destination) || 0) + 1);
    }
    
    const singletonVertices = [];

   for (const [vertex, count] of vertexCount) {
      if (count === 1 && vertex !== start && vertex !== goal) {
        singletonVertices.push(vertex);
      }
    }


  return mstEdges.filter(edge => !singletonVertices.includes(edge.source) && !singletonVertices.includes(edge.destination));

    //return singletonVertices;
  }
  
  removeEdgesConnectedToVertices(edges, vertices) {
    return edges.filter(edge => !vertices.includes(edge.source) && !vertices.includes(edge.destination));
  }

  
}
  
  
function getRandomInt(max) {
  return Math.floor(Math.random() * max);
}


// 使用例

let graph ;
let mstEdges ;
let singletonVertices;
let remainingEdges;
let startVertex ;
let endVertex ;
let hubVertices ;

const vtx=[50,200,350,500,125,275,425,125,275,425];
const vty=[150,150,150,150,75,75,75,225,225,225];


const edges=[
 [0,1,5],[1,2,5],[2,3,5],
 [4,5,5],[5,6,5],[7,8,5],[8,9,5],
 [0,4,5],[0,7,5],[1,4,5],[1,7,5],
 [1,5,5],[1,8,5],[2,5,5],[2,8,5],
 [2,6,5],[2,9,5],[3,6,5],[3,9,5],
 ];
 

function runKruskal(){ 
 graph = new Graph(); 
 
 for(let i=0;i<vtx.length;i++){
  graph.addVertex(vtx[i], vty[i]); 
 }

 for(let i=0;i<edges.length;i++){
  graph.addEdge(edges[i][0],edges[i][1],getRandomInt(10)+1); 
 }
 
 startVertex = 0;
 endVertex = 3; 
 
 
 mstEdges = graph.kruskalWithSteps(graph.kruskalWithSteps());
  
 remainingEdges = graph.findSingletonVertices(mstEdges,startVertex,endVertex); 


 mstEdges.forEach(edge => {
  console.log(`Source: ${edge.source}, Destination: ${edge.destination}, Weight: ${edge.weight}`);
});
 
  console.log(singletonVertices);

  console.log(remainingEdges);
}



function setup() {
 createCanvas(550, 500).parent("p5canvas");
 textSize(17);
 runKruskal();
}


  
function mousePressed() {
 runKruskal();
}
 
 

function draw() {
  background(100);
  
  stroke(255, 255, 155);
  strokeWeight(1);
  for(let i=0;i<graph.vertices.length;i++){
   fill(255);
   circle(graph.vertices[i].x,graph.vertices[i].y,15);
  }
  

  for(let i=0;i<graph.edges.length;i++){
   let snum=graph.edges[i].source;
   let dnum=graph.edges[i].destination;

   let x1=graph.vertices[snum].x;
   let y1=graph.vertices[snum].y;
   let x2=graph.vertices[dnum].x;
   let y2=graph.vertices[dnum].y;
   line(x1,y1,x2,y2);
  }
  
  for(let i=0;i<graph.vertices.length;i++){
   fill(255);
   text(i,graph.vertices[i].x,graph.vertices[i].y-10);
  }
  
  stroke(0, 0, 255);
  fill(255,255,255);
  for(let i=0;i<graph.edges.length;i++){
   let snum=graph.edges[i].source;
   let dnum=graph.edges[i].destination;

   let x1=graph.vertices[snum].x;
   let y1=graph.vertices[snum].y;
   let x2=graph.vertices[dnum].x;
   let y2=graph.vertices[dnum].y;
   text(graph.edges[i].weight,(x1+x2)/2,(y1+y2)/2-10);
  }
  
  stroke(200,255,200);
  strokeWeight(5);
  
  for(let i=0;i<mstEdges.length;i++){
   let snum=mstEdges[i].source;
   let dnum=mstEdges[i].destination;

   let x1=graph.vertices[snum].x;
   let y1=graph.vertices[snum].y;
   let x2=graph.vertices[dnum].x;
   let y2=graph.vertices[dnum].y;
   line(x1,y1,x2,y2);
  }
 }
</script>

</html>

2022年10月26日水曜日

2Dでの線と線の交差判定

 線と線の交差判定



<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.js"></script>
<div id="p5canvas"></div>
<script>   

let lp1; //line 1 point 1
let lp2; //line 1 point 2
let lp3; //line 2 point 1
let lp4; //line 2 point 2
let lpm1;//line 3 point 1 mousexy
let lpm2;//line 3 point 2 

function setup() {
	let sqsize=50;
	createCanvas(400, 400).parent("p5canvas");
	textSize(20);
	lp1=createVector(width / 2-sqsize, height / 2-sqsize);
	lp2=createVector(width / 2+sqsize, height / 2+sqsize);
	lp3=createVector(width / 2-sqsize, height / 2+sqsize);
	lp4=createVector(width / 2+sqsize, height / 2-sqsize);
	lpm1=createVector(width / 2-30, height / 2);
	lpm2=createVector(0,0);
}
function mousePressed() {
	lpm1.set(mouseX,mouseY);
}

function crosscheck( p1,p2,p3,p4)
{
  let a1, a2;
  a1 = (p3.x * p2.y - p3.x * p1.y - p1.x * p2.y + p1.x * p1.y - p2.x * p3.y + p2.x * p1.y + p1.x * p3.y - p1.x * p1.y)*
  (p4.x * p2.y - p4.x * p1.y - p1.x * p2.y + p1.x * p1.y - p2.x * p4.y + p2.x * p1.y + p1.x * p4.y - p1.x * p1.y);
  a2 = (p4.x * p1.y - p4.x * p3.y - p3.x * p1.y + p3.x * p3.y - p1.x * p4.y + p1.x * p3.y + p3.x * p4.y - p3.x * p3.y)*
  (p4.x * p2.y - p4.x * p3.y - p3.x * p2.y + p3.x * p3.y - p2.x * p4.y + p2.x * p3.y + p3.x * p4.y - p3.x * p3.y);
  if(a1<=0&&a2<=0)
     return true;
  else
    return false;
}
function draw() {
	background(100);	
		
	strokeWeight(4);
	stroke(155,255,155);
	line(lp1.x,lp1.y,lp2.x,lp2.y); 
	
	stroke(150,255,255);
	line(lp3.x,lp3.y,lp4.x,lp4.y); 
	
	stroke(0,255,100);
	lpm2.set(mouseX,mouseY);
	line(lpm1.x,lpm1.y,lpm2.x,lpm2.y); 
	
	noStroke();
	fill(255);
	text(crosscheck(lpm1,lpm2,lp1,lp2),10,30);
	text(crosscheck(lpm1,lpm2,lp3,lp4),10,60);
}
</script>

2022年10月25日火曜日

2D ベクトルのdot積とcloss積の使いどころ

 以前組んだプログラムのベクトルのコードを見直した

ドット積とクロス積の使いどころがわかった

"白"が進行方向 "緑"がターゲットへのベクトルの時

ドット積はターゲットが前方180°以内にあれば正

後方だと負になるようだ

クロス積はターゲットが右に居るか左に居るかで正負が

分かれるようだ

vector に.dot()があるが.closs()がvectorオブジェクトを返してくるので

計算式にした(計算結果は同じだった)



<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.js"></script>
<div id="p5canvas"></div>
<script>   

let posmouse; //mouse position
let postarget; //target position

let v1;		//mouse to target 
let v2;		//mouse move direction
let vdot;	//dot product 

function setup() {
	createCanvas(400, 400).parent("p5canvas");
	postarget = createVector(width / 2, height / 2);
	posmouse = createVector(mouseX,mouseY);
	v1=createVector(0,1);
	v2=createVector(1,0);
	textSize(20);
}
function mousePressed() {
	v2=p5.Vector.sub(postarget,posmouse);
	v2.normalize();	
}


function draw() {
	background(100);
	
	posmouse.set(mouseX,mouseY);	
	v1=p5.Vector.sub(postarget,posmouse);
	v1.normalize();
	
	noStroke();
	fill(255);
	
	vdot=v1.x*v2.x+v1.y*v2.y;		//dot product
	text("dot  : "+vdot.toFixed(3),10,30);
	vdot=v1.x*v2.y-v1.y*v2.x;		//closs product
	text("closs:"+vdot.toFixed(3),10,60);

	strokeWeight(4);
	noFill();	
	
	stroke(155,255,155);
	circle(postarget.x,postarget.y,50);	
	stroke(150,255,255);
	circle(posmouse.x,posmouse.y,50);
	
	stroke(0,255,100);
	v1.mult(50);	
	v1.add(posmouse);	
	line(v1.x,v1.y,posmouse.x,posmouse.y); 
		
	let v3=v2.copy();
	v3.mult(50);
	v3.add(posmouse);
	stroke(255,255,200);	
	line(v3.x,v3.y,posmouse.x,posmouse.y);
}
</script>

p5jsでpngをBase64文字列にしてコードに埋め込んでspriteに









Blogger上でp5jsでsprites用の画像を扱うのが面倒そうなので
文字列にして埋め込んでみる
変換コードもコピペしたので残す 
imageで読み込む際に文字列の頭にこれをつける'data:image/png;base64,'


<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.js"></script>
<div id="p5canvas"></div>
<script>   

let img;
let spx=10;
let spy=10;
let timer=0;

function setup() {
  createCanvas(400, 200).parent("p5canvas");
  frameRate(30);
  img = loadImage('data:image/png;base64,'+
  'iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAMAAABA3o1rAAADAFBMVEUAiACIAIi7u7uqzO4AAAAzIiJEMzOId2aZiIi7qqrdzLv/7t3///9VEQB3EQCqIgDMMwD/RAD/dxH/uxH/3SL/7ncRIndEVf9mzP+I3f+7//+ZzO677v8zRBEzZhGI3QC7/wARmXciAEREEVXMZojumar/zN27RFXuu8x3MyKZRETMd2b/mZkzIhFVMyKIVUSZd1W7iGbMqnfuzKr/3cwiEQBEIhGqZiLMdzPdiETumVX/u2b/3Yjd3VURMzMRd3cRu7sR//93ZruZd+4zM2ZmZpmZiLvMu+7//+6ZmaqIiIj/AP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP+9hPPFAAAAAXRSTlMAQObYZgAAAAd0SU1FB+YKGQQ3OaNj0msAAAFZSURBVHjaZVFdSwJBFD3jbpbrVysLPWwamKyW9AX2kOgfsN9bL73agxDRB7Ti2hayllIQtBuVrU53RqOvC3PnzNxzDvfOIJGAjNkmQ1XV6ZanFBAjmJZLbZH3Ow70pEC+ZCGo2xskWDiiGg5QkB6TbzcYk+LElnj1EhmGw4YDrdCl85ZIqgHO06/bvGM8NhXk4eouwF6EIJAOFhFQ9+6K7Mt2mHnm9/CwPBCnCO94Y6DrO5wkwXRBiExOicwMKyV1JxizvETXeJorwd4BYp5LTeIhdoo1wLLB2RXWBSc7gH4LJEU7GaRzQC+t8TaynMbRFHqAPenVd8WYWAG80eIFXRgsh4/zEWD2Zo8QggFxPYxw/y0EasM+zKUmVHM2UF8Qqi7zd9ul0TFq86RQw/fmj29BhJpUUo4ipjxTb1ottPA3tAr9REUgi3Ij/o9QLgPFqkDRKK3N39VPI2h1VzbxKN4AAAAASUVORK5CYII=');
}

function draw() {
	background(0);
	img.resize(32*4,16*4);
	
    if(spx>mouseX)spx--;else if(spx<mouseX) spx++;
    if(spx<0)spx=0;if(spx>350)spx=350;
    if(spy>mouseY)spy--;else if(spy<mouseY)  spy++;    
    if(spy<0)spy=0;if(spy>150)spy=150;
    timer++;
    if(timer>5000)timer=0;
    let flg=parseInt(timer/8)%2;
    image(img, 10, 10, 10*4, 16*4, 10*4, 0, 10*4,16*4);
    image(img, 90, 15, 10*4, 16*4, 0, 0, 10*4,16*4);
    image(img, 150, 30, 10*4, 16*4, 20*4, 0, 10*4,16*4);
    if(flg==0)
    	image(img, spx, spy, 10*4, 16*4, 0, 0, 10*4,16*4);
    else
    image(img, spx, spy+4, 10*4, 15*4, 0, 0, 10*4,16*4);    	
}
</script>

2022年10月23日日曜日

Dall-EとMidjourneyにスプライト用ドット絵を作ってもらう

ドット絵が必要になった AIがに試しに描いてもらった

キーワードはこれ

”pixelart table fantasy cute characters sprites girls cats half   Roguelike maid  quarter view”

Dall-E

NES寄りなドットを作ってくれる







Midjourney

pixelart 寄りなドット絵ができる



つかえそう

ドット絵にする際に使用した

image to pixel のサイト

https://giventofly.github.io/pixelit/#tryit










2022年10月22日土曜日

Blogger で p5js textarea scrollbar

この間のスクロールバー云々をBlogger上でデモ




<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.js"></script><div id="p5canvas"></div>
<script>
let myTextArea;

function setup() {
  createCanvas(400, 300).parent("p5canvas");
  // init textarea
  myTextArea = createElement('textarea').parent("p5canvas");
  myTextArea.attribute("rows","5");
  myTextArea.attribute("cols","20");
  myTextArea.value('0\n1\n2\n3\n4\n5\n6\n7\n0\n1\n2\n3\n4\n5\n6\n7');
  myTextArea.position(20,20);
 }

function draw() {
  background(220);  
  text(" scrollTop "+myTextArea.elt.scrollTop ,20,280); 
}
</script>

2022年10月19日水曜日

Blogger でp5jsがつかえた

”HTMLビュー”でHTMLを編集  divとcanvasを関連付ければ良いみたい

(div id="p5canvas とcreateCanvasの.parent("p5canvas");)

p5js本体はCDNを参照(https://cdnjs.com/libraries/p5.js)

コードはP5サイトのEXAMPLEから(https://p5js.org/examples/3d-geometries.html)


<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.js"></script>
<div id="p5canvas"></div>
<script> 
function setup() {
  createCanvas(710, 400, WEBGL).parent("p5canvas");
}

function draw() {
  background(250);

  translate(-240, -100, 0);
  normalMaterial();
  push();
  rotateZ(frameCount * 0.01);
  rotateX(frameCount * 0.01);
  rotateY(frameCount * 0.01);
  plane(70);
  pop();

  translate(240, 0, 0);
  push();
  rotateZ(frameCount * 0.01);
  rotateX(frameCount * 0.01);
  rotateY(frameCount * 0.01);
  box(70, 70, 70);
  pop();

  translate(240, 0, 0);
  push();
  rotateZ(frameCount * 0.01);
  rotateX(frameCount * 0.01);
  rotateY(frameCount * 0.01);
  cylinder(70, 70);
  pop();

  translate(-240 * 2, 200, 0);
  push();
  rotateZ(frameCount * 0.01);
  rotateX(frameCount * 0.01);
  rotateY(frameCount * 0.01);
  cone(70, 70);
  pop();

  translate(240, 0, 0);
  push();
  rotateZ(frameCount * 0.01);
  rotateX(frameCount * 0.01);
  rotateY(frameCount * 0.01);
  torus(70, 20);
  pop();

  translate(240, 0, 0);
  push();
  rotateZ(frameCount * 0.01);
  rotateX(frameCount * 0.01);
  rotateY(frameCount * 0.01);
  sphere(70);
  pop();
}
</script>

2022年9月28日水曜日

p5js textarea scrollbar ではまったので残しておく

20220928

p5jsでtextareaをつかいたかったのと

スクロールバーのスクロール具合を知りたかったので調べたら

2日ほど潰れてくやしいので記録しておく

scrollTopの前にeltをつければ良いみたい

正道かどうかは不明


ブラウザのデバッグモードの要素のイベントリスナーの

blurのwindowのhandlerの[[scopes]]のスクリプトのmyTxtareaの

eltでその他のメンバーが見られるので必要がアレば探そう


p5js ウェブエディターで以下のコードで検証



let myTextArea;
let btnname=['A','B'];
let butn=[];

function aset(){
  myTextArea.elt.rows=5;
  myTextArea.elt.scrollTop=50;
}

function bset(){
  myTextArea.elt.rows=10;
  myTextArea.elt.scrollTop=100;  
}


function setup() {
  createCanvas(400, 550);
  // init textarea
  myTextArea = createElement('textarea');
  myTextArea.attribute("rows","10");
  myTextArea.attribute("cols","50");
  myTextArea.value('0\n1\n2\n3\n4\n5\n6\n7\n0\n1\n2\n3\n4\n5\n6\n7');
  myTextArea.position(20,20);
  
  //init buttons
  for(let i=0;i<btnname.length;i++){
    butn[i] = createButton(btnname[i]);
    butn[i].position(20+i*50, 230);
  }
  butn[0].mousePressed(aset);
  butn[1].mousePressed(bset);
}

function draw() {
  background(220);  
  text(" scrollTop "+myTextArea.elt.scrollTop ,20,280); 
  text(myTextArea.value(),20,310); 
}

2022年6月10日金曜日

ubuntuの再インストールの覚書

2022 06 09

Firefox  からgoogle chrome をダウンロード < 失敗

ubuntu software から web をダウンロード

web でgoogle chrome をダウンロード

NVIDIA のサイトに行き ドライバ NVIDIA-Linux-x86_64-515.48.07.run をダウンロードしてインストール  <  失敗

ドライバーはCUDA Toolkitでインストールすると良いらしいので

NVIDIA の CUDA Toolkit のサイトに行きselect target platform の質問に答えて

でてきた指示をコピペしてインストール

途中で終了したっぽいが

コンソールで

sudo dpkg --configure -a

と入力するとGPUドライバのインストールは完了したっぽい

2022 06 10
”アプリケーションがデフォルトのキーリング 〜 ”のダイアログを消したい
passwords and keys が 入ってないみたいなので
sudo apt install seahorse でインストール
seahorse を起動すると”パスワードと鍵”がでてるくので
”ログイン”のパスワードには空白を設定して
”デフォルトのキーリング”は設定を削除(chrome などがあった)

設定 > プライバシー > 画面
で ”自動画面ロック”以下のスイッチをオフにする
”ブランクスクリーン”は5分のまま

動画コーデックのインストールはコレだけで済むらしい
sudo apt install ubuntu-restricted-extras
済まなかったのでコレも追加
sudo apt-get install -y gstreamer1.0-plugins-bad


sudo のパスワード入力を省略したい
コンソールで
sudo visudo
エディタに入り
hoge ALL=(ALL:ALL) NOPASSWD: ALL
を最後に追加
hogeはユーザー名

まとめてzip
find * -maxdepth 0 -type d |xargs -l1 -i zip -r {}.zip {}










2022年6月9日木曜日

Ubuntuでトラックボールのボタンのリマッピング設定の保存

xinputでトラックボールのボタンの設定 の変更


xinput list ,xinput get-button-map,xinput query-state,

xinput set-button-map,xinput --get-button-map

とかを使って設定を決める

/usr/share/X11/xorg.conf.d/40-libinput.conf ファイルの下の方に

設定を書き込む


自分の場合はこれ

Section "InputClass"

Identifier "ELECOM TrackBall Mouse HUGE TrackBall"

MatchProduct "ELECOM TrackBall Mouse HUGE TrackBall"

Driver "libinput"

Option  "ButtonMapping" "1 2 3 4 5 6 7 9 8 10 11 2 2"

EndSection

2022年2月10日木曜日

ubuntu20で古いスキャナを使う

 断舎利のため古くなった本を自炊

スキャナはCANNON DR-C125 

前はWINDOWS今はubuntuなのでハマったが

なんとかしたらなんとかなった


まずsane は入ってたから、libsane1,  libsane-common,  sane-utilsをインストール

sudo apt update
sudo apt install libsane1
sudo apt-get update
sudo apt-get install libsane-common
sudo apt-get update
sudo apt-get install sane-utils

どれが必要あるのか無いのかわからなかったので全部入れてみた


ubntu用ドライバは以下のサイトから

https://www.canon.co.uk/support/products/document-scanners/dr-series/imageformula-dr-c125.html?type=drivers&language=&os=linux

ダウンロードしたのがこれ d1224mux_dr125_lnx_drv010.zip 

解凍して cndrvsane-drc125_1.00-0.1_i386.deb をインストール

の途中でエラーで止まる

詳細は以下のサイトに書いてあるようなことらしい

https://bugs.launchpad.net/ubuntu/+source/sane-backends/+bug/1728012

ubuntuのバージョンアップでsanaのディレクトリの構成が変わったからみたい

なので

/usr/ lib/sane

を作りもう一度インストールすると成功した

ディレクトリのなかにはファイルが3つ

それらを

usr/lib/x86_64-linux-gnu/sane

に移動 /usr/ lib/sane は削除

以上でドライバのインストールは出来た


これだけが原因なら他の古いスキャナのドライバのインストール

もできるんじゃないかしら


WINDOWS には CaptureOnTouch なる

ソフトがあったがubuntuにはない

ので xsane を導入

sudo apt-get update
sudo apt-get install xsane

普通に使える

連続スキャンもファイル名に連番追加もjpg,png保存も

読み込み範囲指定もdpi変更その他もろもろできる


結論 ubuntuでDR-C125をつかって自炊はできた

   個人的にはCaptureOnTouchと比べて遜色ない


 



raspiでseleniumの自動化用のファイル作り直し

2024/2/17に不注意でraspiのsdカードを壊し jupyterファイルのバックアップを取らずにos再インストールを試みるという 愚行を重ねたためまたjupyterで作業ファイルを作ることになったので念の為 残しておく 途中なので要らない行も有るかも これだけ再現できれば...