-
-
Save TN8001/98678d6c658ac6201e7b6fd64c28fe2c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://openprocessing.org/sketch/1111225 | |
let _aryR = []; | |
let _limitCount; | |
let _aryTriangle = []; | |
let _aryTriCenter = []; | |
let _count; | |
let _aryInitRot = []; | |
let _aryCentRotYZ = []; | |
let _numSphere; | |
let _aryH = []; | |
let _aryInitNoiseXYZ = []; | |
let _aryNoiseRangeXYZ = []; | |
let _noiseStepT; | |
let _sphereR; | |
let _maxR; | |
function setup() { | |
let canvasSize; | |
if (windowWidth <= windowHeight) { | |
canvasSize = windowWidth; | |
} else { | |
canvasSize = windowHeight; | |
} | |
createCanvas(1112, 834, WEBGL); | |
setAttributes('premultipliedAlpha', true); | |
frameRate(30); | |
colorMode(HSB, 360, 100, 100, 255); | |
noStroke(); | |
_limitCount = 3; | |
_maxR = width / 3; | |
_numSphere = 4; | |
let initH = random(360); | |
let directionH = random([-1, 1]); | |
for (let i = 0; i < _numSphere; i++) { | |
_aryR[i] = _maxR / _numSphere * (i + 1); | |
let createTriangle = new BaseTriangle(_aryR[i], i); | |
_aryH[i] = (initH + 300 / _numSphere * i * directionH + 360) % 360; | |
} | |
for (let i = 0; i < 3; i++) { | |
_aryInitNoiseXYZ[i] = random(100); | |
_aryInitRot[i] = random(360); | |
} | |
_aryNoiseRangeXYZ[0] = 1.0 / 1.5 / 4; | |
_aryNoiseRangeXYZ[1] = 1.0 / 1.5 / 4; | |
_aryNoiseRangeXYZ[2] = 1.0 / 1.5 / 4; | |
_noiseStepT = 0.006; | |
_sphereR = width / 50; | |
_count = 0; | |
} | |
function draw() { | |
background(200 / 255 * 100 * 0); | |
directionalLight(0, 0, 1000, -1, 1, -1); | |
ambientLight(80); | |
rotateX(_aryInitRot[0] + _count / 300); | |
rotateY(_aryInitRot[1] + _count / 100); | |
rotateZ(_aryInitRot[2] + _count / 200); | |
let freq = 4; | |
let d = 4; | |
let colHRange = 0; | |
for (let j = 0; j < _numSphere; j++) { | |
for (let i = 0; i < _aryTriangle[j].length; i++) { | |
let noiseVal = sin(freq * 2 * PI * noise( | |
_aryInitNoiseXYZ[0] + _aryNoiseRangeXYZ[0] * _aryTriCenter[j][i][0] / _maxR, | |
_aryInitNoiseXYZ[1] + _aryNoiseRangeXYZ[1] * _aryTriCenter[j][i][1] / _maxR, | |
_aryInitNoiseXYZ[2] + _aryNoiseRangeXYZ[2] * _aryTriCenter[j][i][2] / _maxR + _noiseStepT * _count | |
)) ** d * 1 + 0; | |
let threshold = 0.5; | |
let ratio = (noiseVal - threshold) / (1 - threshold); | |
if (noiseVal > threshold) { | |
fill(color((_aryH[j] + colHRange * ratio) % 360, 80, 100)); | |
push(); | |
rotateZ(PI / 2); | |
rotateX(-_aryCentRotYZ[j][i][0]); | |
rotateZ(_aryCentRotYZ[j][i][1]); | |
translate(0, -_aryR[j], 0); | |
sphere(_sphereR * ratio); | |
pop(); | |
} | |
} | |
} | |
_count++; | |
} | |
class BaseTriangle { | |
constructor(r, index) { | |
let triangles = []; | |
triangles[0] = [[r, 0, 0], [0, 0, r], [0, -r, 0]]; | |
triangles[1] = [[-r, 0, 0], [0, 0, r], [0, -r, 0]]; | |
triangles[2] = [[r, 0, 0], [0, 0, -r], [0, -r, 0]]; | |
triangles[3] = [[-r, 0, 0], [0, 0, -r], [0, -r, 0]]; | |
triangles[4] = [[r, 0, 0], [0, 0, r], [0, r, 0]]; | |
triangles[5] = [[-r, 0, 0], [0, 0, r], [0, r, 0]]; | |
triangles[6] = [[r, 0, 0], [0, 0, -r], [0, r, 0]]; | |
triangles[7] = [[-r, 0, 0], [0, 0, -r], [0, r, 0]]; | |
_aryTriangle[index] = []; | |
_aryTriCenter[index] = []; | |
_aryCentRotYZ[index] = []; | |
let countObj = 0; | |
for (let i = 0; i < triangles.length; i++) { | |
let newSubTriangle = new SubTriangle(triangles[i], countObj + 1, r, index); | |
} | |
} | |
} | |
class SubTriangle { | |
constructor(triangle, countObj, r, index) { //triangle = [[x1, y1, z1], [x2, y2, z2], [x3, y3, z3]] | |
this.countObj = countObj; | |
if (this.countObj <= _limitCount) { | |
this.XYZ1 = triangle[0]; | |
this.XYZ2 = triangle[1]; | |
this.XYZ3 = triangle[2]; | |
this.divide(this.XYZ1, this.XYZ2, this.XYZ3, r); | |
let newTriangle1 = [this.XYZ1, this.newMidXYZ_1_2, this.newMidXYZ_3_1]; | |
let newTriangle2 = [this.newMidXYZ_1_2, this.XYZ2, this.newMidXYZ_2_3]; | |
let newTriangle3 = [this.newMidXYZ_3_1, this.newMidXYZ_2_3, this.XYZ3]; | |
let newTriangle4 = [this.newMidXYZ_1_2, this.newMidXYZ_2_3, this.newMidXYZ_3_1]; | |
this.triangles = [newTriangle1, newTriangle2, newTriangle3, newTriangle4]; | |
for (let i = 0; i < this.triangles.length; i++) { | |
let newSubTriangle = new SubTriangle(this.triangles[i], this.countObj + 1, r, index); | |
} | |
} else { | |
this.addCenter(triangle, index); //[[x1, y1, z1], [x2, y2, z2], [x3, y3, z3]] -> [ave.x, ave.y, ave.z] | |
this.addCentRotYZ(index); //angle X-Z plane, angle X-Y plane | |
_aryTriangle[index].push(triangle); | |
} | |
} | |
addCenter(triangle, index) { | |
let centX = 0; | |
let centY = 0; | |
let centZ = 0; | |
for (let i = 0; i < triangle.length; i++) { | |
centX += triangle[i][0]; | |
centY += triangle[i][1]; | |
centZ += triangle[i][2]; | |
} | |
centX /= triangle.length; | |
centY /= triangle.length; | |
centZ /= triangle.length; | |
_aryTriCenter[index].push([centX, centY, centZ]); | |
} | |
addCentRotYZ(index) { | |
for (let i = 0; i < _aryTriCenter[index].length; i++) { | |
let rotY = atan2(_aryTriCenter[index][i][2], _aryTriCenter[index][i][0]); | |
let rx = (_aryTriCenter[index][i][2] ** 2 + _aryTriCenter[index][i][0] ** 2) ** 0.5; | |
let ry = _aryTriCenter[index][i][1]; | |
let rotZ = atan2(ry, rx); | |
_aryCentRotYZ[index][i] = [rotY, rotZ]; | |
} | |
} | |
divide(XYZ1, XYZ2, XYZ3, r) { | |
let midXYZ_1_2 = [ | |
(XYZ1[0] + XYZ2[0]) / 2, | |
(XYZ1[1] + XYZ2[1]) / 2, | |
(XYZ1[2] + XYZ2[2]) / 2 | |
]; | |
let midXYZ_2_3 = [ | |
(XYZ2[0] + XYZ3[0]) / 2, | |
(XYZ2[1] + XYZ3[1]) / 2, | |
(XYZ2[2] + XYZ3[2]) / 2 | |
]; | |
let midXYZ_3_1 = [ | |
(XYZ3[0] + XYZ1[0]) / 2, | |
(XYZ3[1] + XYZ1[1]) / 2, | |
(XYZ3[2] + XYZ1[2]) / 2 | |
]; | |
let distMid_1_2 = (midXYZ_1_2[0] ** 2 + midXYZ_1_2[1] ** 2 + midXYZ_1_2[2] ** 2) ** 0.5; | |
let distMid_2_3 = (midXYZ_2_3[0] ** 2 + midXYZ_2_3[1] ** 2 + midXYZ_2_3[2] ** 2) ** 0.5; | |
let distMid_3_1 = (midXYZ_3_1[0] ** 2 + midXYZ_3_1[1] ** 2 + midXYZ_3_1[2] ** 2) ** 0.5; | |
this.newMidXYZ_1_2 = [ | |
midXYZ_1_2[0] / distMid_1_2 * r, | |
midXYZ_1_2[1] / distMid_1_2 * r, | |
midXYZ_1_2[2] / distMid_1_2 * r | |
]; | |
this.newMidXYZ_2_3 = [ | |
midXYZ_2_3[0] / distMid_2_3 * r, | |
midXYZ_2_3[1] / distMid_2_3 * r, | |
midXYZ_2_3[2] / distMid_2_3 * r | |
]; | |
this.newMidXYZ_3_1 = [ | |
midXYZ_3_1[0] / distMid_3_1 * r, | |
midXYZ_3_1[1] / distMid_3_1 * r, | |
midXYZ_3_1[2] / distMid_3_1 * r | |
]; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://openprocessing.org/sketch/1111225 | |
// * コードフォーマット | |
// * (自分的に)不要な処理(mouseReleased・keyPressed) | |
// * 不要な変数はないか(使っていない・ローカル変数でいい) | |
// * const付けまくる | |
const _limitCount = 3; | |
const _numSphere = 4; | |
const _noiseStepT = 0.006; | |
let _sphereR; // width / 50; | |
let _maxR; // width / 3; | |
const _aryInitRot = []; // [random(360), random(360), random(360)] | |
const _aryInitNoiseXYZ = []; // [random(100), random(100), random(100)] | |
const _aryNoiseRangeXYZ = [1.0 / 1.5 / 4, 1.0 / 1.5 / 4, 1.0 / 1.5 / 4]; | |
const _aryR = []; | |
const _aryH = []; | |
const _aryTriangle = []; | |
const _aryTriCenter = []; | |
const _aryCentRotYZ = []; | |
//let _count; // frameCount | |
function setup() { | |
//let canvasSize; // 使っていない | |
createCanvas(1112, 834, WEBGL); | |
setAttributes('premultipliedAlpha', true); | |
frameRate(30); | |
colorMode(HSB, 360, 100, 100, 255); | |
noStroke(); | |
_maxR = width / 3; | |
const initH = random(360); | |
const directionH = random([-1, 1]); | |
for (let i = 0; i < _numSphere; i++) { | |
_aryR[i] = _maxR / _numSphere * (i + 1); | |
new BaseTriangle(_aryR[i], i); | |
_aryH[i] = (initH + 300 / _numSphere * i * directionH + 360) % 360; | |
} | |
for (let i = 0; i < 3; i++) { | |
_aryInitNoiseXYZ[i] = random(100); | |
_aryInitRot[i] = random(360); | |
} | |
_sphereR = width / 50; | |
} | |
function draw() { | |
background(0); | |
directionalLight(0, 0, 1000, -1, 1, -1); | |
ambientLight(80); | |
rotateX(_aryInitRot[0] + frameCount / 300); | |
rotateY(_aryInitRot[1] + frameCount / 100); | |
rotateZ(_aryInitRot[2] + frameCount / 200); | |
const freq = 4; | |
const d = 4; | |
//let colHRange = 0; // 無駄 | |
for (let j = 0; j < _numSphere; j++) { | |
for (let i = 0; i < _aryTriangle[j].length; i++) { | |
const noiseVal = sin(freq * 2 * PI * noise( | |
_aryInitNoiseXYZ[0] + _aryNoiseRangeXYZ[0] * _aryTriCenter[j][i][0] / _maxR, | |
_aryInitNoiseXYZ[1] + _aryNoiseRangeXYZ[1] * _aryTriCenter[j][i][1] / _maxR, | |
_aryInitNoiseXYZ[2] + _aryNoiseRangeXYZ[2] * _aryTriCenter[j][i][2] / _maxR + _noiseStepT * frameCount | |
)) ** d; | |
const threshold = 0.5; | |
const ratio = (noiseVal - threshold) / (1 - threshold); | |
if (noiseVal > threshold) { | |
fill(color(_aryH[j] % 360, 80, 100)); | |
push(); | |
rotateZ(PI / 2); | |
rotateX(-_aryCentRotYZ[j][i][0]); | |
rotateZ(_aryCentRotYZ[j][i][1]); | |
translate(0, -_aryR[j], 0); | |
sphere(_sphereR * ratio); | |
pop(); | |
} | |
} | |
} | |
} | |
class BaseTriangle { | |
constructor(r, index) { | |
const triangles = []; | |
triangles[0] = [[r, 0, 0], [0, 0, r], [0, -r, 0]]; | |
triangles[1] = [[-r, 0, 0], [0, 0, r], [0, -r, 0]]; | |
triangles[2] = [[r, 0, 0], [0, 0, -r], [0, -r, 0]]; | |
triangles[3] = [[-r, 0, 0], [0, 0, -r], [0, -r, 0]]; | |
triangles[4] = [[r, 0, 0], [0, 0, r], [0, r, 0]]; | |
triangles[5] = [[-r, 0, 0], [0, 0, r], [0, r, 0]]; | |
triangles[6] = [[r, 0, 0], [0, 0, -r], [0, r, 0]]; | |
triangles[7] = [[-r, 0, 0], [0, 0, -r], [0, r, 0]]; | |
_aryTriangle[index] = []; | |
_aryTriCenter[index] = []; | |
_aryCentRotYZ[index] = []; | |
//let countObj = 0; // 無駄 | |
for (let i = 0; i < triangles.length; i++) { | |
//let newSubTriangle = // 使っていない | |
new SubTriangle(triangles[i], 1, r, index); | |
} | |
} | |
} | |
class SubTriangle { | |
constructor(triangle, countObj, r, index) { | |
this.countObj = countObj; | |
if (this.countObj <= _limitCount) { | |
this.XYZ1 = triangle[0]; | |
this.XYZ2 = triangle[1]; | |
this.XYZ3 = triangle[2]; | |
this.divide(this.XYZ1, this.XYZ2, this.XYZ3, r); | |
const newTriangle1 = [this.XYZ1, this.newMidXYZ_1_2, this.newMidXYZ_3_1]; | |
const newTriangle2 = [this.newMidXYZ_1_2, this.XYZ2, this.newMidXYZ_2_3]; | |
const newTriangle3 = [this.newMidXYZ_3_1, this.newMidXYZ_2_3, this.XYZ3]; | |
const newTriangle4 = [this.newMidXYZ_1_2, this.newMidXYZ_2_3, this.newMidXYZ_3_1]; | |
this.triangles = [newTriangle1, newTriangle2, newTriangle3, newTriangle4]; | |
for (let i = 0; i < this.triangles.length; i++) { | |
//let newSubTriangle = // 使っていない | |
new SubTriangle(this.triangles[i], this.countObj + 1, r, index); | |
} | |
} else { | |
this.addCenter(triangle, index); | |
this.addCentRotYZ(index); | |
_aryTriangle[index].push(triangle); | |
} | |
} | |
addCenter(triangle, index) { | |
let centX = 0; | |
let centY = 0; | |
let centZ = 0; | |
for (let i = 0; i < triangle.length; i++) { | |
centX += triangle[i][0]; | |
centY += triangle[i][1]; | |
centZ += triangle[i][2]; | |
} | |
centX /= triangle.length; | |
centY /= triangle.length; | |
centZ /= triangle.length; | |
_aryTriCenter[index].push([centX, centY, centZ]); | |
} | |
addCentRotYZ(index) { | |
for (let i = 0; i < _aryTriCenter[index].length; i++) { | |
const rotY = atan2(_aryTriCenter[index][i][2], _aryTriCenter[index][i][0]); | |
const rx = (_aryTriCenter[index][i][2] ** 2 + _aryTriCenter[index][i][0] ** 2) ** 0.5; | |
const ry = _aryTriCenter[index][i][1]; | |
const rotZ = atan2(ry, rx); | |
_aryCentRotYZ[index][i] = [rotY, rotZ]; | |
} | |
} | |
divide(XYZ1, XYZ2, XYZ3, r) { | |
const midXYZ_1_2 = [(XYZ1[0] + XYZ2[0]) / 2, (XYZ1[1] + XYZ2[1]) / 2, (XYZ1[2] + XYZ2[2]) / 2]; | |
const midXYZ_2_3 = [(XYZ2[0] + XYZ3[0]) / 2, (XYZ2[1] + XYZ3[1]) / 2, (XYZ2[2] + XYZ3[2]) / 2]; | |
const midXYZ_3_1 = [(XYZ3[0] + XYZ1[0]) / 2, (XYZ3[1] + XYZ1[1]) / 2, (XYZ3[2] + XYZ1[2]) / 2]; | |
const distMid_1_2 = (midXYZ_1_2[0] ** 2 + midXYZ_1_2[1] ** 2 + midXYZ_1_2[2] ** 2) ** 0.5; | |
const distMid_2_3 = (midXYZ_2_3[0] ** 2 + midXYZ_2_3[1] ** 2 + midXYZ_2_3[2] ** 2) ** 0.5; | |
const distMid_3_1 = (midXYZ_3_1[0] ** 2 + midXYZ_3_1[1] ** 2 + midXYZ_3_1[2] ** 2) ** 0.5; | |
this.newMidXYZ_1_2 = [midXYZ_1_2[0] / distMid_1_2 * r, midXYZ_1_2[1] / distMid_1_2 * r, midXYZ_1_2[2] / distMid_1_2 * r]; | |
this.newMidXYZ_2_3 = [midXYZ_2_3[0] / distMid_2_3 * r, midXYZ_2_3[1] / distMid_2_3 * r, midXYZ_2_3[2] / distMid_2_3 * r]; | |
this.newMidXYZ_3_1 = [midXYZ_3_1[0] / distMid_3_1 * r, midXYZ_3_1[1] / distMid_3_1 * r, midXYZ_3_1[2] / distMid_3_1 * r]; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://openprocessing.org/sketch/1111225 | |
// * drawの先頭にでもブレークポイントを置き配列の構造確認 | |
// * よくよく見ると_aryTriangleは中身を使っていない!! _aryTriCenter[j].lengthでいいやんorz | |
const _limitCount = 3; | |
const _numSphere = 4; | |
const _noiseStepT = 0.006; | |
let _sphereR; // width / 50; | |
let _maxR; // width / 3; | |
const _aryInitRot = []; // [random(360), random(360), random(360)] | |
const _aryInitNoiseXYZ = []; // [random(100), random(100), random(100)] | |
const _aryNoiseRangeXYZ = [1.0 / 1.5 / 4, 1.0 / 1.5 / 4, 1.0 / 1.5 / 4]; | |
const _aryR = []; // float[4] | |
const _aryH = []; // float[4] | |
//const _aryTriangle = []; // float[4][512][3] | |
const _aryTriCenter = []; // float[4][512][3] | |
const _aryCentRotYZ = []; // float[4][512][2] | |
function setup() { | |
createCanvas(1112, 834, WEBGL); | |
setAttributes('premultipliedAlpha', true); | |
frameRate(30); | |
colorMode(HSB, 360, 100, 100, 255); | |
noStroke(); | |
_maxR = width / 3; | |
const initH = random(360); | |
const directionH = random([-1, 1]); | |
for (let i = 0; i < _numSphere; i++) { | |
_aryR[i] = _maxR / _numSphere * (i + 1); | |
new BaseTriangle(_aryR[i], i); | |
_aryH[i] = (initH + 300 / _numSphere * i * directionH + 360) % 360; | |
} | |
for (let i = 0; i < 3; i++) { | |
_aryInitNoiseXYZ[i] = random(100); | |
_aryInitRot[i] = random(360); | |
} | |
_sphereR = width / 50; | |
} | |
function draw() { | |
background(0); | |
directionalLight(0, 0, 1000, -1, 1, -1); | |
ambientLight(80); | |
rotateX(_aryInitRot[0] + frameCount / 300); | |
rotateY(_aryInitRot[1] + frameCount / 100); | |
rotateZ(_aryInitRot[2] + frameCount / 200); | |
const freq = 4; | |
const d = 4; | |
for (let j = 0; j < _numSphere; j++) { | |
for (let i = 0; i < _aryTriCenter[j].length; i++) { | |
const noiseVal = sin(freq * 2 * PI * noise( | |
_aryInitNoiseXYZ[0] + _aryNoiseRangeXYZ[0] * _aryTriCenter[j][i][0] / _maxR, | |
_aryInitNoiseXYZ[1] + _aryNoiseRangeXYZ[1] * _aryTriCenter[j][i][1] / _maxR, | |
_aryInitNoiseXYZ[2] + _aryNoiseRangeXYZ[2] * _aryTriCenter[j][i][2] / _maxR + _noiseStepT * frameCount | |
)) ** d; | |
const threshold = 0.5; | |
const ratio = (noiseVal - threshold) / (1 - threshold); | |
if (noiseVal > threshold) { | |
fill(color(_aryH[j] % 360, 80, 100)); | |
push(); | |
rotateZ(PI / 2); | |
rotateX(-_aryCentRotYZ[j][i][0]); | |
rotateZ(_aryCentRotYZ[j][i][1]); | |
translate(0, -_aryR[j], 0); | |
sphere(_sphereR * ratio); | |
pop(); | |
} | |
} | |
} | |
} | |
class BaseTriangle { | |
constructor(r, index) { | |
const triangles = []; | |
triangles[0] = [[r, 0, 0], [0, 0, r], [0, -r, 0]]; | |
triangles[1] = [[-r, 0, 0], [0, 0, r], [0, -r, 0]]; | |
triangles[2] = [[r, 0, 0], [0, 0, -r], [0, -r, 0]]; | |
triangles[3] = [[-r, 0, 0], [0, 0, -r], [0, -r, 0]]; | |
triangles[4] = [[r, 0, 0], [0, 0, r], [0, r, 0]]; | |
triangles[5] = [[-r, 0, 0], [0, 0, r], [0, r, 0]]; | |
triangles[6] = [[r, 0, 0], [0, 0, -r], [0, r, 0]]; | |
triangles[7] = [[-r, 0, 0], [0, 0, -r], [0, r, 0]]; | |
//_aryTriangle[index] = []; | |
_aryTriCenter[index] = []; | |
_aryCentRotYZ[index] = []; | |
for (let i = 0; i < triangles.length; i++) { | |
new SubTriangle(triangles[i], 1, r, index); | |
} | |
} | |
} | |
class SubTriangle { | |
constructor(triangle, countObj, r, index) { | |
this.countObj = countObj; | |
if (this.countObj <= _limitCount) { | |
this.XYZ1 = triangle[0]; | |
this.XYZ2 = triangle[1]; | |
this.XYZ3 = triangle[2]; | |
this.divide(this.XYZ1, this.XYZ2, this.XYZ3, r); | |
const newTriangle1 = [this.XYZ1, this.newMidXYZ_1_2, this.newMidXYZ_3_1]; | |
const newTriangle2 = [this.newMidXYZ_1_2, this.XYZ2, this.newMidXYZ_2_3]; | |
const newTriangle3 = [this.newMidXYZ_3_1, this.newMidXYZ_2_3, this.XYZ3]; | |
const newTriangle4 = [this.newMidXYZ_1_2, this.newMidXYZ_2_3, this.newMidXYZ_3_1]; | |
this.triangles = [newTriangle1, newTriangle2, newTriangle3, newTriangle4]; | |
for (let i = 0; i < this.triangles.length; i++) { | |
new SubTriangle(this.triangles[i], this.countObj + 1, r, index); | |
} | |
} else { | |
this.addCenter(triangle, index); | |
this.addCentRotYZ(index); | |
//_aryTriangle[index].push(triangle); | |
} | |
} | |
addCenter(triangle, index) { | |
let centX = 0; | |
let centY = 0; | |
let centZ = 0; | |
for (let i = 0; i < triangle.length; i++) { | |
centX += triangle[i][0]; | |
centY += triangle[i][1]; | |
centZ += triangle[i][2]; | |
} | |
centX /= triangle.length; | |
centY /= triangle.length; | |
centZ /= triangle.length; | |
_aryTriCenter[index].push([centX, centY, centZ]); | |
} | |
addCentRotYZ(index) { | |
for (let i = 0; i < _aryTriCenter[index].length; i++) { | |
const rotY = atan2(_aryTriCenter[index][i][2], _aryTriCenter[index][i][0]); | |
const rx = (_aryTriCenter[index][i][2] ** 2 + _aryTriCenter[index][i][0] ** 2) ** 0.5; | |
const ry = _aryTriCenter[index][i][1]; | |
const rotZ = atan2(ry, rx); | |
_aryCentRotYZ[index][i] = [rotY, rotZ]; | |
} | |
} | |
divide(XYZ1, XYZ2, XYZ3, r) { | |
const midXYZ_1_2 = [(XYZ1[0] + XYZ2[0]) / 2, (XYZ1[1] + XYZ2[1]) / 2, (XYZ1[2] + XYZ2[2]) / 2]; | |
const midXYZ_2_3 = [(XYZ2[0] + XYZ3[0]) / 2, (XYZ2[1] + XYZ3[1]) / 2, (XYZ2[2] + XYZ3[2]) / 2]; | |
const midXYZ_3_1 = [(XYZ3[0] + XYZ1[0]) / 2, (XYZ3[1] + XYZ1[1]) / 2, (XYZ3[2] + XYZ1[2]) / 2]; | |
const distMid_1_2 = (midXYZ_1_2[0] ** 2 + midXYZ_1_2[1] ** 2 + midXYZ_1_2[2] ** 2) ** 0.5; | |
const distMid_2_3 = (midXYZ_2_3[0] ** 2 + midXYZ_2_3[1] ** 2 + midXYZ_2_3[2] ** 2) ** 0.5; | |
const distMid_3_1 = (midXYZ_3_1[0] ** 2 + midXYZ_3_1[1] ** 2 + midXYZ_3_1[2] ** 2) ** 0.5; | |
this.newMidXYZ_1_2 = [midXYZ_1_2[0] / distMid_1_2 * r, midXYZ_1_2[1] / distMid_1_2 * r, midXYZ_1_2[2] / distMid_1_2 * r]; | |
this.newMidXYZ_2_3 = [midXYZ_2_3[0] / distMid_2_3 * r, midXYZ_2_3[1] / distMid_2_3 * r, midXYZ_2_3[2] / distMid_2_3 * r]; | |
this.newMidXYZ_3_1 = [midXYZ_3_1[0] / distMid_3_1 * r, midXYZ_3_1[1] / distMid_3_1 * r, midXYZ_3_1[2] / distMid_3_1 * r]; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://openprocessing.org/sketch/1111225 | |
// * Vectorにしやすいもの(_InitRot・_InitNoise・_NoiseRange)をまず変更 | |
// * _aryTriCenter・_aryCentRotYZの3次元目を注意深くVectorに変更 | |
const _limitCount = 3; | |
const _numSphere = 4; | |
const _noiseStepT = 0.006; | |
let _sphereR; // width / 50; | |
let _maxR; // width / 3; | |
let _InitRot; // new p5.Vector(random(360), random(360), random(360)); | |
let _InitNoise; // new p5.Vector(random(100), random(100), random(100)); | |
let _NoiseRange; // new p5.Vector(1.0 / 1.5 / 4, 1.0 / 1.5 / 4, 1.0 / 1.5 / 4); | |
const _aryR = []; // float[4] | |
const _aryH = []; // float[4] | |
const _aryTriCenter = []; // p5.Vector[4][512] | |
const _aryCentRotYZ = []; // p5.Vector[4][512] | |
function setup() { | |
createCanvas(1112, 834, WEBGL); | |
setAttributes('premultipliedAlpha', true); | |
frameRate(30); | |
colorMode(HSB, 360, 100, 100, 255); | |
noStroke(); | |
_maxR = width / 3; | |
_sphereR = width / 50; | |
//for (let i = 0; i < 3; i++) { | |
// _InitNoise[i] = random(100); | |
// _InitRot[i] = random(360); | |
//} | |
_InitRot = new p5.Vector(random(360), random(360), random(360)); | |
_InitNoise = new p5.Vector(random(100), random(100), random(100)); | |
_NoiseRange = new p5.Vector(1.0 / 1.5 / 4, 1.0 / 1.5 / 4, 1.0 / 1.5 / 4); | |
const initH = random(360); | |
const directionH = random([-1, 1]); | |
for (let i = 0; i < _numSphere; i++) { | |
_aryR[i] = _maxR / _numSphere * (i + 1); | |
new BaseTriangle(_aryR[i], i); | |
_aryH[i] = (initH + 300 / _numSphere * i * directionH + 360) % 360; | |
} | |
} | |
function draw() { | |
background(0); | |
directionalLight(0, 0, 1000, -1, 1, -1); | |
ambientLight(80); | |
rotateX(_InitRot.x + frameCount / 300); | |
rotateY(_InitRot.y + frameCount / 100); | |
rotateZ(_InitRot.z + frameCount / 200); | |
const freq = 4; | |
const d = 4; | |
for (let j = 0; j < _numSphere; j++) { | |
for (let i = 0; i < _aryTriCenter[j].length; i++) { | |
const noiseVal = sin(freq * 2 * PI * noise( | |
_InitNoise.x + _NoiseRange.x * _aryTriCenter[j][i].x / _maxR, | |
_InitNoise.y + _NoiseRange.y * _aryTriCenter[j][i].y / _maxR, | |
_InitNoise.z + _NoiseRange.z * _aryTriCenter[j][i].z / _maxR + _noiseStepT * frameCount | |
)) ** d; | |
const threshold = 0.5; | |
const ratio = (noiseVal - threshold) / (1 - threshold); | |
if (noiseVal > threshold) { | |
fill(color(_aryH[j] % 360, 80, 100)); | |
push(); | |
rotateZ(PI / 2); | |
rotateX(-_aryCentRotYZ[j][i].x); | |
rotateZ(_aryCentRotYZ[j][i].z); | |
translate(0, -_aryR[j], 0); | |
sphere(_sphereR * ratio); | |
pop(); | |
} | |
} | |
} | |
} | |
class BaseTriangle { | |
constructor(r, index) { | |
const triangles = []; | |
triangles[0] = [[r, 0, 0], [0, 0, r], [0, -r, 0]]; | |
triangles[1] = [[-r, 0, 0], [0, 0, r], [0, -r, 0]]; | |
triangles[2] = [[r, 0, 0], [0, 0, -r], [0, -r, 0]]; | |
triangles[3] = [[-r, 0, 0], [0, 0, -r], [0, -r, 0]]; | |
triangles[4] = [[r, 0, 0], [0, 0, r], [0, r, 0]]; | |
triangles[5] = [[-r, 0, 0], [0, 0, r], [0, r, 0]]; | |
triangles[6] = [[r, 0, 0], [0, 0, -r], [0, r, 0]]; | |
triangles[7] = [[-r, 0, 0], [0, 0, -r], [0, r, 0]]; | |
_aryTriCenter[index] = []; | |
_aryCentRotYZ[index] = []; | |
for (let i = 0; i < triangles.length; i++) { | |
new SubTriangle(triangles[i], 1, r, index); | |
} | |
} | |
} | |
class SubTriangle { | |
constructor(triangle, countObj, r, index) { | |
this.countObj = countObj; | |
if (this.countObj <= _limitCount) { | |
this.XYZ1 = triangle[0]; | |
this.XYZ2 = triangle[1]; | |
this.XYZ3 = triangle[2]; | |
this.divide(this.XYZ1, this.XYZ2, this.XYZ3, r); | |
const newTriangle1 = [this.XYZ1, this.newMidXYZ_1_2, this.newMidXYZ_3_1]; | |
const newTriangle2 = [this.newMidXYZ_1_2, this.XYZ2, this.newMidXYZ_2_3]; | |
const newTriangle3 = [this.newMidXYZ_3_1, this.newMidXYZ_2_3, this.XYZ3]; | |
const newTriangle4 = [this.newMidXYZ_1_2, this.newMidXYZ_2_3, this.newMidXYZ_3_1]; | |
this.triangles = [newTriangle1, newTriangle2, newTriangle3, newTriangle4]; | |
for (let i = 0; i < this.triangles.length; i++) { | |
new SubTriangle(this.triangles[i], this.countObj + 1, r, index); | |
} | |
} else { | |
this.addCenter(triangle, index); | |
this.addCentRotYZ(index); | |
} | |
} | |
addCenter(triangle, index) { | |
let centX = 0; | |
let centY = 0; | |
let centZ = 0; | |
for (let i = 0; i < triangle.length; i++) { | |
centX += triangle[i][0]; | |
centY += triangle[i][1]; | |
centZ += triangle[i][2]; | |
} | |
centX /= triangle.length; | |
centY /= triangle.length; | |
centZ /= triangle.length; | |
_aryTriCenter[index].push(new p5.Vector(centX, centY, centZ)); | |
} | |
addCentRotYZ(index) { | |
for (let i = 0; i < _aryTriCenter[index].length; i++) { | |
const rotY = atan2(_aryTriCenter[index][i].z, _aryTriCenter[index][i].x); | |
const rx = (_aryTriCenter[index][i].z ** 2 + _aryTriCenter[index][i].x ** 2) ** 0.5; | |
const ry = _aryTriCenter[index][i].y; | |
const rotZ = atan2(ry, rx); | |
_aryCentRotYZ[index][i] = new p5.Vector(rotY, 0, rotZ); // 位置は使う側に合わせた | |
} | |
} | |
divide(XYZ1, XYZ2, XYZ3, r) { | |
const midXYZ_1_2 = [(XYZ1[0] + XYZ2[0]) / 2, (XYZ1[1] + XYZ2[1]) / 2, (XYZ1[2] + XYZ2[2]) / 2]; | |
const midXYZ_2_3 = [(XYZ2[0] + XYZ3[0]) / 2, (XYZ2[1] + XYZ3[1]) / 2, (XYZ2[2] + XYZ3[2]) / 2]; | |
const midXYZ_3_1 = [(XYZ3[0] + XYZ1[0]) / 2, (XYZ3[1] + XYZ1[1]) / 2, (XYZ3[2] + XYZ1[2]) / 2]; | |
const distMid_1_2 = (midXYZ_1_2[0] ** 2 + midXYZ_1_2[1] ** 2 + midXYZ_1_2[2] ** 2) ** 0.5; | |
const distMid_2_3 = (midXYZ_2_3[0] ** 2 + midXYZ_2_3[1] ** 2 + midXYZ_2_3[2] ** 2) ** 0.5; | |
const distMid_3_1 = (midXYZ_3_1[0] ** 2 + midXYZ_3_1[1] ** 2 + midXYZ_3_1[2] ** 2) ** 0.5; | |
this.newMidXYZ_1_2 = [midXYZ_1_2[0] / distMid_1_2 * r, midXYZ_1_2[1] / distMid_1_2 * r, midXYZ_1_2[2] / distMid_1_2 * r]; | |
this.newMidXYZ_2_3 = [midXYZ_2_3[0] / distMid_2_3 * r, midXYZ_2_3[1] / distMid_2_3 * r, midXYZ_2_3[2] / distMid_2_3 * r]; | |
this.newMidXYZ_3_1 = [midXYZ_3_1[0] / distMid_3_1 * r, midXYZ_3_1[1] / distMid_3_1 * r, midXYZ_3_1[2] / distMid_3_1 * r]; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://openprocessing.org/sketch/1111225 | |
// * まともなクラスの使い方をしたいので、下準備として今のクラスを関数化 | |
const _limitCount = 3; | |
const _numSphere = 4; | |
const _noiseStepT = 0.006; | |
let _sphereR; // width / 50; | |
let _maxR; // width / 3; | |
let _InitRot; // new p5.Vector(random(360), random(360), random(360)); | |
let _InitNoise; // new p5.Vector(random(100), random(100), random(100)); | |
let _NoiseRange; // new p5.Vector(1.0 / 1.5 / 4, 1.0 / 1.5 / 4, 1.0 / 1.5 / 4); | |
const _aryR = []; // float[4] | |
const _aryH = []; // float[4] | |
const _aryTriCenter = []; // p5.Vector[4][512] | |
const _aryCentRotYZ = []; // p5.Vector[4][512] | |
function setup() { | |
createCanvas(1112, 834, WEBGL); | |
setAttributes('premultipliedAlpha', true); | |
frameRate(30); | |
colorMode(HSB, 360, 100, 100, 255); | |
noStroke(); | |
_maxR = width / 3; | |
_sphereR = width / 50; | |
_InitRot = new p5.Vector(random(360), random(360), random(360)); | |
_InitNoise = new p5.Vector(random(100), random(100), random(100)); | |
_NoiseRange = new p5.Vector(1.0 / 1.5 / 4, 1.0 / 1.5 / 4, 1.0 / 1.5 / 4); | |
const initH = random(360); | |
const directionH = random([-1, 1]); | |
for (let i = 0; i < _numSphere; i++) { | |
_aryR[i] = _maxR / _numSphere * (i + 1); | |
BaseTriangle(_aryR[i], i); | |
_aryH[i] = (initH + 300 / _numSphere * i * directionH + 360) % 360; | |
} | |
} | |
function draw() { | |
background(0); | |
directionalLight(0, 0, 1000, -1, 1, -1); | |
ambientLight(80); | |
rotateX(_InitRot.x + frameCount / 300); | |
rotateY(_InitRot.y + frameCount / 100); | |
rotateZ(_InitRot.z + frameCount / 200); | |
const freq = 4; | |
const d = 4; | |
for (let j = 0; j < _numSphere; j++) { | |
for (let i = 0; i < _aryTriCenter[j].length; i++) { | |
const noiseVal = sin(freq * 2 * PI * noise( | |
_InitNoise.x + _NoiseRange.x * _aryTriCenter[j][i].x / _maxR, | |
_InitNoise.y + _NoiseRange.y * _aryTriCenter[j][i].y / _maxR, | |
_InitNoise.z + _NoiseRange.z * _aryTriCenter[j][i].z / _maxR + _noiseStepT * frameCount | |
)) ** d; | |
const threshold = 0.5; | |
const ratio = (noiseVal - threshold) / (1 - threshold); | |
if (noiseVal > threshold) { | |
fill(color(_aryH[j] % 360, 80, 100)); | |
push(); | |
rotateZ(PI / 2); | |
rotateX(-_aryCentRotYZ[j][i].x); | |
rotateZ(_aryCentRotYZ[j][i].z); | |
translate(0, -_aryR[j], 0); | |
sphere(_sphereR * ratio); | |
pop(); | |
} | |
} | |
} | |
} | |
//class BaseTriangle { | |
function BaseTriangle(r, index) { | |
const triangles = []; | |
triangles[0] = [[r, 0, 0], [0, 0, r], [0, -r, 0]]; | |
triangles[1] = [[-r, 0, 0], [0, 0, r], [0, -r, 0]]; | |
triangles[2] = [[r, 0, 0], [0, 0, -r], [0, -r, 0]]; | |
triangles[3] = [[-r, 0, 0], [0, 0, -r], [0, -r, 0]]; | |
triangles[4] = [[r, 0, 0], [0, 0, r], [0, r, 0]]; | |
triangles[5] = [[-r, 0, 0], [0, 0, r], [0, r, 0]]; | |
triangles[6] = [[r, 0, 0], [0, 0, -r], [0, r, 0]]; | |
triangles[7] = [[-r, 0, 0], [0, 0, -r], [0, r, 0]]; | |
_aryTriCenter[index] = []; | |
_aryCentRotYZ[index] = []; | |
for (let i = 0; i < triangles.length; i++) { | |
SubTriangle(triangles[i], 1, r, index); | |
} | |
} | |
//class SubTriangle { | |
function SubTriangle(triangle, countObj, r, index) { | |
//this.countObj = countObj; | |
if (countObj <= _limitCount) { | |
const XYZ1 = triangle[0]; | |
const XYZ2 = triangle[1]; | |
const XYZ3 = triangle[2]; | |
const [newMidXYZ_1_2, newMidXYZ_2_3, newMidXYZ_3_1] = divide(XYZ1, XYZ2, XYZ3, r); | |
const newTriangle1 = [XYZ1, newMidXYZ_1_2, newMidXYZ_3_1]; | |
const newTriangle2 = [newMidXYZ_1_2, XYZ2, newMidXYZ_2_3]; | |
const newTriangle3 = [newMidXYZ_3_1, newMidXYZ_2_3, XYZ3]; | |
const newTriangle4 = [newMidXYZ_1_2, newMidXYZ_2_3, newMidXYZ_3_1]; | |
const triangles = [newTriangle1, newTriangle2, newTriangle3, newTriangle4]; | |
for (let i = 0; i < triangles.length; i++) { | |
SubTriangle(triangles[i], countObj + 1, r, index); | |
} | |
} else { | |
addCenter(triangle, index); | |
addCentRotYZ(index); | |
} | |
} | |
function addCenter(triangle, index) { | |
let centX = 0; | |
let centY = 0; | |
let centZ = 0; | |
for (let i = 0; i < triangle.length; i++) { | |
centX += triangle[i][0]; | |
centY += triangle[i][1]; | |
centZ += triangle[i][2]; | |
} | |
centX /= triangle.length; | |
centY /= triangle.length; | |
centZ /= triangle.length; | |
_aryTriCenter[index].push(new p5.Vector(centX, centY, centZ)); | |
} | |
function addCentRotYZ(index) { | |
for (let i = 0; i < _aryTriCenter[index].length; i++) { | |
const rotY = atan2(_aryTriCenter[index][i].z, _aryTriCenter[index][i].x); | |
const rx = (_aryTriCenter[index][i].z ** 2 + _aryTriCenter[index][i].x ** 2) ** 0.5; | |
const ry = _aryTriCenter[index][i].y; | |
const rotZ = atan2(ry, rx); | |
_aryCentRotYZ[index][i] = new p5.Vector(rotY, 0, rotZ); // 位置は使う側に合わせた | |
} | |
} | |
function divide(XYZ1, XYZ2, XYZ3, r) { | |
const midXYZ_1_2 = [(XYZ1[0] + XYZ2[0]) / 2, (XYZ1[1] + XYZ2[1]) / 2, (XYZ1[2] + XYZ2[2]) / 2]; | |
const midXYZ_2_3 = [(XYZ2[0] + XYZ3[0]) / 2, (XYZ2[1] + XYZ3[1]) / 2, (XYZ2[2] + XYZ3[2]) / 2]; | |
const midXYZ_3_1 = [(XYZ3[0] + XYZ1[0]) / 2, (XYZ3[1] + XYZ1[1]) / 2, (XYZ3[2] + XYZ1[2]) / 2]; | |
const distMid_1_2 = (midXYZ_1_2[0] ** 2 + midXYZ_1_2[1] ** 2 + midXYZ_1_2[2] ** 2) ** 0.5; | |
const distMid_2_3 = (midXYZ_2_3[0] ** 2 + midXYZ_2_3[1] ** 2 + midXYZ_2_3[2] ** 2) ** 0.5; | |
const distMid_3_1 = (midXYZ_3_1[0] ** 2 + midXYZ_3_1[1] ** 2 + midXYZ_3_1[2] ** 2) ** 0.5; | |
const newMidXYZ_1_2 = [midXYZ_1_2[0] / distMid_1_2 * r, midXYZ_1_2[1] / distMid_1_2 * r, midXYZ_1_2[2] / distMid_1_2 * r]; | |
const newMidXYZ_2_3 = [midXYZ_2_3[0] / distMid_2_3 * r, midXYZ_2_3[1] / distMid_2_3 * r, midXYZ_2_3[2] / distMid_2_3 * r]; | |
const newMidXYZ_3_1 = [midXYZ_3_1[0] / distMid_3_1 * r, midXYZ_3_1[1] / distMid_3_1 * r, midXYZ_3_1[2] / distMid_3_1 * r]; | |
return [newMidXYZ_1_2, newMidXYZ_2_3, newMidXYZ_3_1]; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://openprocessing.org/sketch/1111225 | |
// * ちょこちょこ出てくるtriangleが本当に3点あるのか、2点4点だったりしないか確認 | |
// * ↑確認がてらaddCenter・divideのリファクタリング | |
const _limitCount = 3; | |
const _numSphere = 4; | |
const _noiseStepT = 0.006; | |
let _sphereR; // width / 50; | |
let _maxR; // width / 3; | |
let _InitRot; // new p5.Vector(random(360), random(360), random(360)); | |
let _InitNoise; // new p5.Vector(random(100), random(100), random(100)); | |
let _NoiseRange; // new p5.Vector(1.0 / 1.5 / 4, 1.0 / 1.5 / 4, 1.0 / 1.5 / 4); | |
const _aryR = []; // float[4] | |
const _aryH = []; // float[4] | |
const _aryTriCenter = []; // p5.Vector[4][512] | |
const _aryCentRotYZ = []; // p5.Vector[4][512] | |
function setup() { | |
createCanvas(1112, 834, WEBGL); | |
setAttributes('premultipliedAlpha', true); | |
frameRate(30); | |
colorMode(HSB, 360, 100, 100, 255); | |
noStroke(); | |
_maxR = width / 3; | |
_sphereR = width / 50; | |
_InitRot = new p5.Vector(random(360), random(360), random(360)); | |
_InitNoise = new p5.Vector(random(100), random(100), random(100)); | |
_NoiseRange = new p5.Vector(1.0 / 1.5 / 4, 1.0 / 1.5 / 4, 1.0 / 1.5 / 4); | |
const initH = random(360); | |
const directionH = random([-1, 1]); | |
for (let i = 0; i < _numSphere; i++) { | |
_aryR[i] = _maxR / _numSphere * (i + 1); | |
BaseTriangle(_aryR[i], i); | |
_aryH[i] = (initH + 300 / _numSphere * i * directionH + 360) % 360; | |
} | |
} | |
function draw() { | |
background(0); | |
directionalLight(0, 0, 1000, -1, 1, -1); | |
ambientLight(80); | |
rotateX(_InitRot.x + frameCount / 300); | |
rotateY(_InitRot.y + frameCount / 100); | |
rotateZ(_InitRot.z + frameCount / 200); | |
const freq = 4; | |
const d = 4; | |
for (let j = 0; j < _numSphere; j++) { | |
for (let i = 0; i < _aryTriCenter[j].length; i++) { | |
const noiseVal = sin(freq * 2 * PI * noise( | |
_InitNoise.x + _NoiseRange.x * _aryTriCenter[j][i].x / _maxR, | |
_InitNoise.y + _NoiseRange.y * _aryTriCenter[j][i].y / _maxR, | |
_InitNoise.z + _NoiseRange.z * _aryTriCenter[j][i].z / _maxR + _noiseStepT * frameCount | |
)) ** d; | |
const threshold = 0.5; | |
const ratio = (noiseVal - threshold) / (1 - threshold); | |
if (noiseVal > threshold) { | |
fill(color(_aryH[j] % 360, 80, 100)); | |
push(); | |
rotateZ(PI / 2); | |
rotateX(-_aryCentRotYZ[j][i].x); | |
rotateZ(_aryCentRotYZ[j][i].z); | |
translate(0, -_aryR[j], 0); | |
sphere(_sphereR * ratio); | |
pop(); | |
} | |
} | |
} | |
} | |
function BaseTriangle(r, index) { | |
const triangles = []; | |
triangles[0] = [[r, 0, 0], [0, 0, r], [0, -r, 0]]; | |
triangles[1] = [[-r, 0, 0], [0, 0, r], [0, -r, 0]]; | |
triangles[2] = [[r, 0, 0], [0, 0, -r], [0, -r, 0]]; | |
triangles[3] = [[-r, 0, 0], [0, 0, -r], [0, -r, 0]]; | |
triangles[4] = [[r, 0, 0], [0, 0, r], [0, r, 0]]; | |
triangles[5] = [[-r, 0, 0], [0, 0, r], [0, r, 0]]; | |
triangles[6] = [[r, 0, 0], [0, 0, -r], [0, r, 0]]; | |
triangles[7] = [[-r, 0, 0], [0, 0, -r], [0, r, 0]]; | |
_aryTriCenter[index] = []; | |
_aryCentRotYZ[index] = []; | |
for (let i = 0; i < triangles.length; i++) { | |
SubTriangle(triangles[i], 1, r, index); | |
} | |
} | |
function SubTriangle(triangle, countObj, r, index) { | |
console.assert(triangle.length == 3, "not triangle", triangle.length); | |
if (countObj <= _limitCount) { | |
const XYZ1 = triangle[0]; | |
const XYZ2 = triangle[1]; | |
const XYZ3 = triangle[2]; | |
const [newMidXYZ_1_2, newMidXYZ_2_3, newMidXYZ_3_1] = divide(XYZ1, XYZ2, XYZ3, r); | |
const newTriangle1 = [XYZ1, newMidXYZ_1_2, newMidXYZ_3_1]; | |
const newTriangle2 = [newMidXYZ_1_2, XYZ2, newMidXYZ_2_3]; | |
const newTriangle3 = [newMidXYZ_3_1, newMidXYZ_2_3, XYZ3]; | |
const newTriangle4 = [newMidXYZ_1_2, newMidXYZ_2_3, newMidXYZ_3_1]; | |
const triangles = [newTriangle1, newTriangle2, newTriangle3, newTriangle4]; | |
for (let i = 0; i < triangles.length; i++) { | |
SubTriangle(triangles[i], countObj + 1, r, index); | |
} | |
} else { | |
addCenter(triangle, index); | |
addCentRotYZ(index); | |
} | |
} | |
function addCenter(triangle, index) { | |
console.assert(triangle.length == 3, "not triangle", triangle.length); | |
let centX = 0; | |
let centY = 0; | |
let centZ = 0; | |
for (let i = 0; i < triangle.length; i++) { | |
centX += triangle[i][0]; | |
centY += triangle[i][1]; | |
centZ += triangle[i][2]; | |
} | |
centX /= triangle.length; | |
centY /= triangle.length; | |
centZ /= triangle.length; | |
const v1 = new p5.Vector(triangle[0][0], triangle[0][1], triangle[0][2]); | |
const v2 = new p5.Vector(triangle[1][0], triangle[1][1], triangle[1][2]); | |
const v3 = new p5.Vector(triangle[2][0], triangle[2][1], triangle[2][2]); | |
const center = p5.Vector.add(v1, v2).add(v3).div(3); | |
console.assert(center.x == centX, "centX", center.x, centX); | |
console.assert(center.y == centY, "centY", center.y, centY); | |
console.assert(center.z == centZ, "centZ", center.z, centZ); | |
_aryTriCenter[index].push(new p5.Vector(centX, centY, centZ)); | |
} | |
function addCentRotYZ(index) { | |
for (let i = 0; i < _aryTriCenter[index].length; i++) { | |
const rotY = atan2(_aryTriCenter[index][i].z, _aryTriCenter[index][i].x); | |
const rx = (_aryTriCenter[index][i].z ** 2 + _aryTriCenter[index][i].x ** 2) ** 0.5; | |
const ry = _aryTriCenter[index][i].y; | |
const rotZ = atan2(ry, rx); | |
_aryCentRotYZ[index][i] = new p5.Vector(rotY, 0, rotZ); // 位置は使う側に合わせた | |
} | |
} | |
function divide(XYZ1, XYZ2, XYZ3, r) { | |
const midXYZ_1_2 = [(XYZ1[0] + XYZ2[0]) / 2, (XYZ1[1] + XYZ2[1]) / 2, (XYZ1[2] + XYZ2[2]) / 2]; | |
const midXYZ_2_3 = [(XYZ2[0] + XYZ3[0]) / 2, (XYZ2[1] + XYZ3[1]) / 2, (XYZ2[2] + XYZ3[2]) / 2]; | |
const midXYZ_3_1 = [(XYZ3[0] + XYZ1[0]) / 2, (XYZ3[1] + XYZ1[1]) / 2, (XYZ3[2] + XYZ1[2]) / 2]; | |
const distMid_1_2 = (midXYZ_1_2[0] ** 2 + midXYZ_1_2[1] ** 2 + midXYZ_1_2[2] ** 2) ** 0.5; | |
const distMid_2_3 = (midXYZ_2_3[0] ** 2 + midXYZ_2_3[1] ** 2 + midXYZ_2_3[2] ** 2) ** 0.5; | |
const distMid_3_1 = (midXYZ_3_1[0] ** 2 + midXYZ_3_1[1] ** 2 + midXYZ_3_1[2] ** 2) ** 0.5; | |
const newMidXYZ_1_2 = [midXYZ_1_2[0] / distMid_1_2 * r, midXYZ_1_2[1] / distMid_1_2 * r, midXYZ_1_2[2] / distMid_1_2 * r]; | |
const newMidXYZ_2_3 = [midXYZ_2_3[0] / distMid_2_3 * r, midXYZ_2_3[1] / distMid_2_3 * r, midXYZ_2_3[2] / distMid_2_3 * r]; | |
const newMidXYZ_3_1 = [midXYZ_3_1[0] / distMid_3_1 * r, midXYZ_3_1[1] / distMid_3_1 * r, midXYZ_3_1[2] / distMid_3_1 * r]; | |
const v1 = new p5.Vector(XYZ1[0], XYZ1[1], XYZ1[2]); | |
const v2 = new p5.Vector(XYZ2[0], XYZ2[1], XYZ2[2]); | |
const v3 = new p5.Vector(XYZ3[0], XYZ3[1], XYZ3[2]); | |
const mid12 = p5.Vector.lerp(v1, v2, 0.5); | |
const mid23 = p5.Vector.lerp(v2, v3, 0.5); | |
const mid31 = p5.Vector.lerp(v3, v1, 0.5); | |
const dist12 = mid12.mag(); | |
const dist23 = mid23.mag(); | |
const dist31 = mid31.mag(); | |
const newv1 = mid12.div(dist12).mult(r); | |
const newv2 = mid23.div(dist23).mult(r); | |
const newv3 = mid31.div(dist31).mult(r); | |
console.assert(newv1.x == newMidXYZ_1_2[0] && newv1.y == newMidXYZ_1_2[1] && newv1.z == newMidXYZ_1_2[2], "newMidXYZ_1_2"); | |
console.assert(newv2.x == newMidXYZ_2_3[0] && newv2.y == newMidXYZ_2_3[1] && newv2.z == newMidXYZ_2_3[2], "newMidXYZ_2_3"); | |
console.assert(newv3.x == newMidXYZ_3_1[0] && newv3.y == newMidXYZ_3_1[1] && newv3.z == newMidXYZ_3_1[2], "newMidXYZ_3_1"); | |
return [newMidXYZ_1_2, newMidXYZ_2_3, newMidXYZ_3_1]; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://openprocessing.org/sketch/1111225 | |
// * そろそろTriangleクラスに取り掛かる | |
const _limitCount = 3; | |
const _numSphere = 4; | |
const _noiseStepT = 0.006; | |
let _sphereR; // width / 50; | |
let _maxR; // width / 3; | |
let _InitRot; // new p5.Vector(random(360), random(360), random(360)); | |
let _InitNoise; // new p5.Vector(random(100), random(100), random(100)); | |
let _NoiseRange; // new p5.Vector(1.0 / 1.5 / 4, 1.0 / 1.5 / 4, 1.0 / 1.5 / 4); | |
const _aryR = []; // float[4] | |
const _aryH = []; // float[4] | |
const _aryTriCenter = []; // p5.Vector[4][512] | |
const _aryCentRotYZ = []; // p5.Vector[4][512] | |
function setup() { | |
createCanvas(1112, 834, WEBGL); | |
setAttributes('premultipliedAlpha', true); | |
frameRate(30); | |
colorMode(HSB, 360, 100, 100, 255); | |
noStroke(); | |
_maxR = width / 3; | |
_sphereR = width / 50; | |
_InitRot = new p5.Vector(random(360), random(360), random(360)); | |
_InitNoise = new p5.Vector(random(100), random(100), random(100)); | |
_NoiseRange = new p5.Vector(1.0 / 1.5 / 4, 1.0 / 1.5 / 4, 1.0 / 1.5 / 4); | |
const initH = random(360); | |
const directionH = random([-1, 1]); | |
for (let i = 0; i < _numSphere; i++) { | |
_aryR[i] = _maxR / _numSphere * (i + 1); | |
BaseTriangle(_aryR[i], i); | |
_aryH[i] = (initH + 300 / _numSphere * i * directionH + 360) % 360; | |
} | |
} | |
function draw() { | |
background(0); | |
directionalLight(0, 0, 1000, -1, 1, -1); | |
ambientLight(80); | |
rotateX(_InitRot.x + frameCount / 300); | |
rotateY(_InitRot.y + frameCount / 100); | |
rotateZ(_InitRot.z + frameCount / 200); | |
const freq = 4; | |
const d = 4; | |
for (let j = 0; j < _numSphere; j++) { | |
for (let i = 0; i < _aryTriCenter[j].length; i++) { | |
const noiseVal = sin(freq * 2 * PI * noise( | |
_InitNoise.x + _NoiseRange.x * _aryTriCenter[j][i].x / _maxR, | |
_InitNoise.y + _NoiseRange.y * _aryTriCenter[j][i].y / _maxR, | |
_InitNoise.z + _NoiseRange.z * _aryTriCenter[j][i].z / _maxR + _noiseStepT * frameCount | |
)) ** d; | |
const threshold = 0.5; | |
const ratio = (noiseVal - threshold) / (1 - threshold); | |
if (noiseVal > threshold) { | |
fill(color(_aryH[j] % 360, 80, 100)); | |
push(); | |
rotateZ(PI / 2); | |
rotateX(-_aryCentRotYZ[j][i].x); | |
rotateZ(_aryCentRotYZ[j][i].z); | |
translate(0, -_aryR[j], 0); | |
sphere(_sphereR * ratio); | |
pop(); | |
} | |
} | |
} | |
} | |
function BaseTriangle(r, index) { | |
_aryTriCenter[index] = []; | |
_aryCentRotYZ[index] = []; | |
const triangles = [ | |
new Triangle2(+r, 0, 0, 0, 0, +r, 0, -r, 0), new Triangle2(-r, 0, 0, 0, 0, +r, 0, -r, 0), | |
new Triangle2(+r, 0, 0, 0, 0, -r, 0, -r, 0), new Triangle2(-r, 0, 0, 0, 0, -r, 0, -r, 0), | |
new Triangle2(+r, 0, 0, 0, 0, +r, 0, +r, 0), new Triangle2(-r, 0, 0, 0, 0, +r, 0, +r, 0), | |
new Triangle2(+r, 0, 0, 0, 0, -r, 0, +r, 0), new Triangle2(-r, 0, 0, 0, 0, -r, 0, +r, 0)]; | |
for (let i = 0; i < triangles.length; i++) { | |
SubTriangle(triangles[i], 1, r, index); | |
} | |
} | |
function SubTriangle(triangle, countObj, r, index) { | |
if (countObj <= _limitCount) { | |
const midTriangle = divide(triangle, r); | |
const newTriangle1 = new Triangle(triangle.v1, midTriangle.v1, midTriangle.v3); | |
const newTriangle2 = new Triangle(midTriangle.v1, triangle.v2, midTriangle.v2); | |
const newTriangle3 = new Triangle(midTriangle.v3, midTriangle.v2, triangle.v3); | |
const triangles = [newTriangle1, newTriangle2, newTriangle3, midTriangle]; | |
for (let i = 0; i < triangles.length; i++) { | |
SubTriangle(triangles[i], countObj + 1, r, index); | |
} | |
} else { | |
addCenter(triangle, index); | |
addCentRotYZ(index); | |
} | |
} | |
function addCenter(triangle, index) { | |
const center = p5.Vector.add(triangle.v1, triangle.v2).add(triangle.v3).div(3); | |
_aryTriCenter[index].push(center); | |
} | |
function addCentRotYZ(index) { | |
for (let i = 0; i < _aryTriCenter[index].length; i++) { | |
const rotY = atan2(_aryTriCenter[index][i].z, _aryTriCenter[index][i].x); | |
const rx = (_aryTriCenter[index][i].z ** 2 + _aryTriCenter[index][i].x ** 2) ** 0.5; | |
const ry = _aryTriCenter[index][i].y; | |
const rotZ = atan2(ry, rx); | |
_aryCentRotYZ[index][i] = new p5.Vector(rotY, 0, rotZ); // 位置は使う側に合わせた | |
} | |
} | |
function divide(triangle, r) { | |
const mid12 = p5.Vector.lerp(triangle.v1, triangle.v2, 0.5); | |
const mid23 = p5.Vector.lerp(triangle.v2, triangle.v3, 0.5); | |
const mid31 = p5.Vector.lerp(triangle.v3, triangle.v1, 0.5); | |
const newv1 = mid12.div(mid12.mag()).mult(r); | |
const newv2 = mid23.div(mid23.mag()).mult(r); | |
const newv3 = mid31.div(mid31.mag()).mult(r); | |
return new Triangle(newv1, newv2, newv3); | |
} | |
class Triangle { | |
constructor(v1, v2, v3) { | |
this.v1 = v1; | |
this.v2 = v2; | |
this.v3 = v3; | |
} | |
} | |
class Triangle2 { // jsはコンストラクタをオーバーロードできない!! | |
constructor(x1, y1, z1, x2, y2, z2, x3, y3, z3) { | |
this.v1 = new p5.Vector(x1, y1, z1); | |
this.v2 = new p5.Vector(x2, y2, z2); | |
this.v3 = new p5.Vector(x3, y3, z3); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://openprocessing.org/sketch/1111225 | |
// * Sphereクラスもつくりますかぁ | |
// * SphereクラスのaryTriCenter・aryCentRotYZがいまいち。3点を使うならTriangleにまとめるところだが。。。 | |
// * どう見ても無駄なことをしているaddCentRotYZをほんとに無駄か確認 | |
const _limitCount = 3; | |
const _numSphere = 4; | |
const _noiseStepT = 0.006; | |
let _sphereR; // width / 50; | |
let _maxR; // width / 3; | |
let _InitRot; // new p5.Vector(random(360), random(360), random(360)); | |
let _InitNoise; // new p5.Vector(random(100), random(100), random(100)); | |
let _NoiseRange; // new p5.Vector(1.0 / 1.5 / 4, 1.0 / 1.5 / 4, 1.0 / 1.5 / 4); | |
//const _aryR = []; // float[4] | |
//const _aryH = []; // float[4] | |
//const _aryTriCenter = []; // p5.Vector[4][512] | |
//const _aryCentRotYZ = []; // p5.Vector[4][512] | |
const _spheres = []; // Sphere[4] | |
function setup() { | |
createCanvas(1112, 834, WEBGL); | |
setAttributes('premultipliedAlpha', true); | |
frameRate(30); | |
colorMode(HSB, 360, 100, 100, 255); | |
noStroke(); | |
_maxR = width / 3; | |
_sphereR = width / 50; | |
_InitRot = new p5.Vector(random(360), random(360), random(360)); | |
_InitNoise = new p5.Vector(random(100), random(100), random(100)); | |
_NoiseRange = new p5.Vector(1.0 / 1.5 / 4, 1.0 / 1.5 / 4, 1.0 / 1.5 / 4); | |
const initH = random(360); | |
const directionH = random([-1, 1]); | |
for (let i = 0; i < _numSphere; i++) { | |
const radius = _maxR / _numSphere * (i + 1); | |
const hue = (initH + 300 / _numSphere * i * directionH + 360) % 360; | |
_spheres.push(new Sphere(radius, hue)); | |
BaseTriangle(radius, i); | |
} | |
} | |
function draw() { | |
background(0); | |
directionalLight(0, 0, 1000, -1, 1, -1); | |
ambientLight(80); | |
rotateX(_InitRot.x + frameCount / 300); | |
rotateY(_InitRot.y + frameCount / 100); | |
rotateZ(_InitRot.z + frameCount / 200); | |
const freq = 4; | |
const d = 4; | |
for (const sph of _spheres) { | |
for (let i = 0; i < sph.aryTriCenter.length; i++) { | |
const noiseVal = sin(freq * 2 * PI * noise( | |
_InitNoise.x + _NoiseRange.x * sph.aryTriCenter[i].x / _maxR, | |
_InitNoise.y + _NoiseRange.y * sph.aryTriCenter[i].y / _maxR, | |
_InitNoise.z + _NoiseRange.z * sph.aryTriCenter[i].z / _maxR + _noiseStepT * frameCount | |
)) ** d; | |
const threshold = 0.5; | |
const ratio = (noiseVal - threshold) / (1 - threshold); | |
if (noiseVal > threshold) { | |
fill(color(sph.hue % 360, 80, 100)); | |
push(); | |
rotateZ(PI / 2); | |
rotateX(- sph.aryCentRotYZ[i].x); | |
rotateZ(sph.aryCentRotYZ[i].z); | |
translate(0, -sph.radius, 0); | |
sphere(_sphereR * ratio); | |
pop(); | |
} | |
} | |
} | |
} | |
function BaseTriangle(r, index) { | |
//_aryTriCenter[index] = []; | |
//_aryCentRotYZ[index] = []; | |
const triangles = [ | |
new Triangle2(+r, 0, 0, 0, 0, +r, 0, -r, 0), new Triangle2(-r, 0, 0, 0, 0, +r, 0, -r, 0), | |
new Triangle2(+r, 0, 0, 0, 0, -r, 0, -r, 0), new Triangle2(-r, 0, 0, 0, 0, -r, 0, -r, 0), | |
new Triangle2(+r, 0, 0, 0, 0, +r, 0, +r, 0), new Triangle2(-r, 0, 0, 0, 0, +r, 0, +r, 0), | |
new Triangle2(+r, 0, 0, 0, 0, -r, 0, +r, 0), new Triangle2(-r, 0, 0, 0, 0, -r, 0, +r, 0)]; | |
for (let i = 0; i < triangles.length; i++) { | |
SubTriangle(triangles[i], 1, r, index); | |
} | |
} | |
function SubTriangle(triangle, countObj, r, index) { | |
if (countObj <= _limitCount) { | |
const midTriangle = divide(triangle, r); | |
const newTriangle1 = new Triangle(triangle.v1, midTriangle.v1, midTriangle.v3); | |
const newTriangle2 = new Triangle(midTriangle.v1, triangle.v2, midTriangle.v2); | |
const newTriangle3 = new Triangle(midTriangle.v3, midTriangle.v2, triangle.v3); | |
const triangles = [newTriangle1, newTriangle2, newTriangle3, midTriangle]; | |
for (let i = 0; i < triangles.length; i++) { | |
SubTriangle(triangles[i], countObj + 1, r, index); | |
} | |
} else { | |
addCenter(triangle, index); | |
addCentRotYZ(index); | |
} | |
} | |
function addCenter(triangle, index) { | |
const center = p5.Vector.add(triangle.v1, triangle.v2).add(triangle.v3).div(3); | |
_spheres[index].aryTriCenter.push(center); | |
} | |
function addCentRotYZ(index) { | |
for (let i = 0; i < _spheres[index].aryTriCenter.length; i++) { | |
const rotY = atan2(_spheres[index].aryTriCenter[i].z, _spheres[index].aryTriCenter[i].x); | |
const rx = (_spheres[index].aryTriCenter[i].z ** 2 + _spheres[index].aryTriCenter[i].x ** 2) ** 0.5; | |
const ry = _spheres[index].aryTriCenter[i].y; | |
const rotZ = atan2(ry, rx); | |
// 最後のを設定したいだけなのに、毎回前のも再計算している 非常に無駄 | |
if (i != _spheres[index].aryTriCenter.length - 1) { | |
const x = _spheres[index].aryCentRotYZ[i].x; | |
const y = _spheres[index].aryCentRotYZ[i].y; | |
const z = _spheres[index].aryCentRotYZ[i].z; | |
console.assert(x == rotY, "addCentRotYZ"); | |
console.assert(y == 0, "addCentRotYZ"); | |
console.assert(z == rotZ, "addCentRotYZ"); | |
} | |
_spheres[index].aryCentRotYZ[i] = new p5.Vector(rotY, 0, rotZ); // 位置は使う側に合わせた | |
} | |
} | |
function divide(triangle, r) { | |
const mid12 = p5.Vector.lerp(triangle.v1, triangle.v2, 0.5); | |
const mid23 = p5.Vector.lerp(triangle.v2, triangle.v3, 0.5); | |
const mid31 = p5.Vector.lerp(triangle.v3, triangle.v1, 0.5); | |
const newv1 = mid12.div(mid12.mag()).mult(r); | |
const newv2 = mid23.div(mid23.mag()).mult(r); | |
const newv3 = mid31.div(mid31.mag()).mult(r); | |
return new Triangle(newv1, newv2, newv3); | |
} | |
class Triangle { | |
constructor(v1, v2, v3) { | |
this.v1 = v1; | |
this.v2 = v2; | |
this.v3 = v3; | |
} | |
} | |
class Triangle2 { // jsはコンストラクタをオーバーロードできない!! | |
constructor(x1, y1, z1, x2, y2, z2, x3, y3, z3) { | |
this.v1 = new p5.Vector(x1, y1, z1); | |
this.v2 = new p5.Vector(x2, y2, z2); | |
this.v3 = new p5.Vector(x3, y3, z3); | |
} | |
} | |
class Sphere { | |
constructor(radius, hue) { | |
this.radius = radius; | |
this.hue = hue; | |
this.aryTriCenter = []; // p5.Vector[512] | |
this.aryCentRotYZ = []; // p5.Vector[512] | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://openprocessing.org/sketch/1111225 | |
// * SphereクラスにPoint[] points をつくることにする(に、ともないaddCenter・addCentRotYZ吸収) | |
// * noiseVal・rotationリファクタ | |
const _limitCount = 3; | |
const _numSphere = 4; | |
const _noiseStepT = 0.006; | |
let _sphereR; // width / 50; | |
let _maxR; // width / 3; | |
let _InitRot; // new p5.Vector(random(360), random(360), random(360)); | |
let _InitNoise; // new p5.Vector(random(100), random(100), random(100)); | |
let _NoiseRange; // new p5.Vector(1.0 / 1.5 / 4, 1.0 / 1.5 / 4, 1.0 / 1.5 / 4); | |
const _spheres = []; // Sphere[4] | |
function setup() { | |
createCanvas(1112, 834, WEBGL); | |
setAttributes('premultipliedAlpha', true); | |
frameRate(30); | |
colorMode(HSB, 360, 100, 100, 255); | |
noStroke(); | |
_maxR = width / 3; | |
_sphereR = width / 50; | |
_InitRot = new p5.Vector(random(360), random(360), random(360)); | |
_InitNoise = new p5.Vector(random(100), random(100), random(100)); | |
_NoiseRange = new p5.Vector(1.0 / 1.5 / 4, 1.0 / 1.5 / 4, 1.0 / 1.5 / 4); | |
const initH = random(360); | |
const directionH = random([-1, 1]); | |
for (let i = 0; i < _numSphere; i++) { | |
const radius = _maxR / _numSphere * (i + 1); | |
const hue = (initH + 300 / _numSphere * i * directionH + 360) % 360; | |
_spheres.push(new Sphere(radius, hue)); | |
BaseTriangle(radius, i); | |
} | |
} | |
function draw() { | |
background(0); | |
directionalLight(0, 0, 1000, -1, 1, -1); | |
ambientLight(80); | |
rotateX(_InitRot.x + frameCount / 300); | |
rotateY(_InitRot.y + frameCount / 100); | |
rotateZ(_InitRot.z + frameCount / 200); | |
const freq = 4; | |
const d = 4; | |
for (const sph of _spheres) { | |
for (const point of sph.points) { | |
const noiseVal = sin(freq * 2 * PI * noise( | |
_InitNoise.x + _NoiseRange.x * point.center.x / _maxR, | |
_InitNoise.y + _NoiseRange.y * point.center.y / _maxR, | |
_InitNoise.z + _NoiseRange.z * point.center.z / _maxR + _noiseStepT * frameCount | |
)) ** d; | |
const v = p5.Vector.mult(_NoiseRange, point.center).div(_maxR).add(_InitNoise); | |
const f = noise(v.x, v.y, v.z + _noiseStepT * frameCount); | |
const val = pow(sin(freq * TWO_PI * f), d); | |
console.assert(noiseVal == val, "noiseVal", noiseVal, val); | |
const threshold = 0.5; | |
const ratio = (noiseVal - threshold) / (1 - threshold); | |
if (noiseVal > threshold) { | |
fill(color(sph.hue % 360, 80, 100)); | |
push(); | |
rotateZ(PI / 2); | |
rotateX(-point.rotation.x); | |
rotateZ(point.rotation.z); | |
translate(0, -sph.radius, 0); | |
sphere(_sphereR * ratio); | |
pop(); | |
} | |
} | |
} | |
} | |
function BaseTriangle(r, index) { | |
const triangles = [ | |
new Triangle2(+r, 0, 0, 0, 0, +r, 0, -r, 0), new Triangle2(-r, 0, 0, 0, 0, +r, 0, -r, 0), | |
new Triangle2(+r, 0, 0, 0, 0, -r, 0, -r, 0), new Triangle2(-r, 0, 0, 0, 0, -r, 0, -r, 0), | |
new Triangle2(+r, 0, 0, 0, 0, +r, 0, +r, 0), new Triangle2(-r, 0, 0, 0, 0, +r, 0, +r, 0), | |
new Triangle2(+r, 0, 0, 0, 0, -r, 0, +r, 0), new Triangle2(-r, 0, 0, 0, 0, -r, 0, +r, 0)]; | |
for (const triangle of triangles) { | |
SubTriangle(triangle, 1, r, index); | |
} | |
} | |
function SubTriangle(triangle, countObj, r, index) { | |
if (countObj <= _limitCount) { | |
const midTriangle = divide(triangle, r); | |
const newTriangle1 = new Triangle(triangle.v1, midTriangle.v1, midTriangle.v3); | |
const newTriangle2 = new Triangle(midTriangle.v1, triangle.v2, midTriangle.v2); | |
const newTriangle3 = new Triangle(midTriangle.v3, midTriangle.v2, triangle.v3); | |
const triangles = [newTriangle1, newTriangle2, newTriangle3, midTriangle]; | |
for (const t of triangles) { | |
SubTriangle(t, countObj + 1, r, index); | |
} | |
} else { | |
//addCenter(triangle, index); | |
//addCentRotYZ(index); | |
const point = new Point(triangle); | |
_spheres[index].points.push(point); | |
} | |
} | |
function divide(triangle, r) { | |
const mid12 = p5.Vector.lerp(triangle.v1, triangle.v2, 0.5); | |
const mid23 = p5.Vector.lerp(triangle.v2, triangle.v3, 0.5); | |
const mid31 = p5.Vector.lerp(triangle.v3, triangle.v1, 0.5); | |
const newv1 = mid12.div(mid12.mag()).mult(r); | |
const newv2 = mid23.div(mid23.mag()).mult(r); | |
const newv3 = mid31.div(mid31.mag()).mult(r); | |
return new Triangle(newv1, newv2, newv3); | |
} | |
class Triangle { | |
constructor(v1, v2, v3) { | |
this.v1 = v1; | |
this.v2 = v2; | |
this.v3 = v3; | |
} | |
} | |
class Triangle2 { // jsはコンストラクタをオーバーロードできない!! | |
constructor(x1, y1, z1, x2, y2, z2, x3, y3, z3) { | |
this.v1 = new p5.Vector(x1, y1, z1); | |
this.v2 = new p5.Vector(x2, y2, z2); | |
this.v3 = new p5.Vector(x3, y3, z3); | |
} | |
} | |
class Sphere { | |
constructor(radius, hue) { | |
this.radius = radius; | |
this.hue = hue; | |
this.points = []; // Point[512] | |
} | |
} | |
class Point { | |
constructor(triangle) { | |
this.center = p5.Vector.add(triangle.v1, triangle.v2).add(triangle.v3).div(3); | |
const rotY = atan2(this.center.z, this.center.x); | |
const rx = (this.center.z ** 2 + this.center.x ** 2) ** 0.5; | |
const ry = this.center.y; | |
const rotZ = atan2(ry, rx); | |
const copy = this.center.copy(); | |
copy.y = 0; | |
const x = atan2(this.center.z, this.center.x); | |
const z = atan2(this.center.y, copy.mag()); | |
console.assert(x == rotY, "rotY", x, rotY); | |
console.assert(z == rotZ, "rotZ", z, rotZ); | |
this.rotation = new p5.Vector(rotY, 0, rotZ); // 位置は使う側に合わせた | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://openprocessing.org/sketch/1111225 | |
// * divideメソッド化 | |
// * 変数名変更等他細々 | |
// * drawをクラス側に回したい気もするが、(translateがなければPointで描きたかった)まあいいでしょう | |
const SPHERE_NUM = 4; | |
const COUNT_LIMIT = 3; | |
const NOISE_STEP = 0.006; | |
let SPHERE_RADIUS; // width / 50; | |
let MAX_SPHERE_RADIUS; // width / 3; | |
let INIT_ROTATION; // new p5.Vector(random(360), random(360), random(360)); | |
let INIT_NOISE; // new p5.Vector(random(100), random(100), random(100)); | |
let NOISE_RANGE; // new p5.Vector(1.0 / 1.5 / 4, 1.0 / 1.5 / 4, 1.0 / 1.5 / 4); | |
const _spheres = []; // Sphere[4] | |
function setup() { | |
createCanvas(1112, 834, WEBGL); | |
setAttributes('premultipliedAlpha', true); | |
frameRate(30); | |
colorMode(HSB, 360, 100, 100, 255); | |
noStroke(); | |
MAX_SPHERE_RADIUS = width / 3; | |
SPHERE_RADIUS = width / 50; | |
INIT_ROTATION = new p5.Vector(random(360), random(360), random(360)); | |
INIT_NOISE = new p5.Vector(random(100), random(100), random(100)); | |
NOISE_RANGE = new p5.Vector(1.0 / 1.5 / 4, 1.0 / 1.5 / 4, 1.0 / 1.5 / 4); | |
const initHue = random(360); | |
const initDirection = random([-1, 1]); | |
for (let i = 0; i < SPHERE_NUM; i++) { | |
const r = MAX_SPHERE_RADIUS / SPHERE_NUM * (i + 1); | |
const hue = (initHue + 300 / SPHERE_NUM * i * initDirection + 360) % 360; | |
_spheres.push(new Sphere(r, hue)); | |
const triangles = [ | |
new Triangle2(+r, 0, 0, 0, 0, +r, 0, -r, 0), new Triangle2(-r, 0, 0, 0, 0, +r, 0, -r, 0), | |
new Triangle2(+r, 0, 0, 0, 0, -r, 0, -r, 0), new Triangle2(-r, 0, 0, 0, 0, -r, 0, -r, 0), | |
new Triangle2(+r, 0, 0, 0, 0, +r, 0, +r, 0), new Triangle2(-r, 0, 0, 0, 0, +r, 0, +r, 0), | |
new Triangle2(+r, 0, 0, 0, 0, -r, 0, +r, 0), new Triangle2(-r, 0, 0, 0, 0, -r, 0, +r, 0)]; | |
for (const triangle of triangles) { | |
addPoints(triangle, 1, r, i); | |
} | |
} | |
} | |
function addPoints(triangle, count, radius, index) { | |
if (count <= COUNT_LIMIT) { | |
const midTriangle = triangle.divide(radius); | |
const triangles = [ | |
new Triangle(triangle.v1, midTriangle.v1, midTriangle.v3), | |
new Triangle(midTriangle.v1, triangle.v2, midTriangle.v2), | |
new Triangle(midTriangle.v3, midTriangle.v2, triangle.v3), | |
midTriangle]; | |
for (const t of triangles) { | |
addPoints(t, count + 1, radius, index); | |
} | |
} else { | |
_spheres[index].points.push(new Point(triangle)); | |
} | |
} | |
function draw() { | |
background(0); | |
directionalLight(0, 0, 1000, -1, 1, -1); | |
ambientLight(80); | |
rotateX(INIT_ROTATION.x + frameCount / 300); | |
rotateY(INIT_ROTATION.y + frameCount / 100); | |
rotateZ(INIT_ROTATION.z + frameCount / 200); | |
const freq = 4; | |
const d = 4; | |
const threshold = 0.5; | |
for (const sph of _spheres) { | |
for (const point of sph.points) { | |
const v = p5.Vector.mult(NOISE_RANGE, point.center).div(MAX_SPHERE_RADIUS).add(INIT_NOISE); | |
const f = noise(v.x, v.y, v.z + NOISE_STEP * frameCount); | |
const noiseValue = pow(sin(freq * TWO_PI * f), d); | |
const ratio = (noiseValue - threshold) / (1 - threshold); | |
if (threshold < noiseValue) { | |
fill(sph.hue, 80, 100); | |
push(); | |
rotateZ(HALF_PI); | |
rotateX(-point.rotation.x); | |
rotateZ(point.rotation.z); | |
translate(0, -sph.radius, 0); | |
sphere(SPHERE_RADIUS * ratio); | |
pop(); | |
} | |
} | |
} | |
} | |
class Triangle { | |
constructor(v1, v2, v3) { | |
this.v1 = v1; | |
this.v2 = v2; | |
this.v3 = v3; | |
} | |
divide(radius) { | |
const mid12 = p5.Vector.lerp(this.v1, this.v2, 0.5); | |
const mid23 = p5.Vector.lerp(this.v2, this.v3, 0.5); | |
const mid31 = p5.Vector.lerp(this.v3, this.v1, 0.5); | |
const newv1 = mid12.div(mid12.mag()).mult(radius); | |
const newv2 = mid23.div(mid23.mag()).mult(radius); | |
const newv3 = mid31.div(mid31.mag()).mult(radius); | |
return new Triangle(newv1, newv2, newv3); | |
} | |
} | |
class Triangle2 { // jsはコンストラクタをオーバーロードできない!! | |
constructor(x1, y1, z1, x2, y2, z2, x3, y3, z3) { | |
this.v1 = new p5.Vector(x1, y1, z1); | |
this.v2 = new p5.Vector(x2, y2, z2); | |
this.v3 = new p5.Vector(x3, y3, z3); | |
} | |
divide(radius) { | |
return new Triangle(this.v1, this.v2, this.v3).divide(radius); | |
} | |
} | |
class Sphere { | |
constructor(radius, hue) { | |
this.radius = radius; | |
this.hue = hue; | |
this.points = []; // Point[512] | |
} | |
} | |
class Point { | |
constructor(triangle) { | |
this.center = p5.Vector.add(triangle.v1, triangle.v2).add(triangle.v3).div(3); | |
const copy = this.center.copy(); | |
copy.y = 0; | |
const x = atan2(this.center.z, this.center.x); | |
const z = atan2(this.center.y, copy.mag()); | |
this.rotation = new p5.Vector(x, 0, z); // 位置は使う側に合わせた | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://openprocessing.org/sketch/1111225 | |
final int SPHERE_NUM = 4; | |
final int COUNT_LIMIT = 3; | |
final float NOISE_STEP = 0.006; | |
float SPHERE_RADIUS; // width / 50.0; | |
float MAX_SPHERE_RADIUS; // width / 3.0; | |
final PVector INIT_ROTATION = new PVector(random(360), random(360), random(360)); | |
final PVector INIT_NOISE = new PVector(random(100), random(100), random(100)); | |
final PVector NOISE_RANGE = new PVector(1.0 / 1.5 / 4, 1.0 / 1.5 / 4, 1.0 / 1.5 / 4); | |
final Sphere[] _spheres = new Sphere[SPHERE_NUM]; | |
void setup() { | |
size(1112, 834, P3D); | |
//setAttributes('premultipliedAlpha', true); | |
//frameRate(30); | |
sphereDetail(12); // デフォルト30 | |
colorMode(HSB, 360, 100, 100, 255); | |
noStroke(); | |
MAX_SPHERE_RADIUS = width / 3.0; | |
SPHERE_RADIUS = width / 50.0; | |
final float initHue = random(360); | |
final int initDirection = int(random(2)) * 2 - 1; // [-1, 1] | |
for (int i = 0; i < SPHERE_NUM; i++) { | |
final float r = MAX_SPHERE_RADIUS / float(SPHERE_NUM) * (i + 1); | |
final float hue = (initHue + 300 / float(SPHERE_NUM) * i * initDirection + 360) % 360; | |
_spheres[i] = new Sphere(r, hue); | |
final Triangle[] triangles = { | |
new Triangle(+r, 0, 0, 0, 0, +r, 0, -r, 0), new Triangle(-r, 0, 0, 0, 0, +r, 0, -r, 0), | |
new Triangle(+r, 0, 0, 0, 0, -r, 0, -r, 0), new Triangle(-r, 0, 0, 0, 0, -r, 0, -r, 0), | |
new Triangle(+r, 0, 0, 0, 0, +r, 0, +r, 0), new Triangle(-r, 0, 0, 0, 0, +r, 0, +r, 0), | |
new Triangle(+r, 0, 0, 0, 0, -r, 0, +r, 0), new Triangle(-r, 0, 0, 0, 0, -r, 0, +r, 0)}; | |
for (final Triangle triangle : triangles) { | |
addPoints(triangle, 1, r, i); | |
} | |
} | |
} | |
void addPoints(final Triangle triangle, final int count, final float radius, final int index) { | |
if (count <= COUNT_LIMIT) { | |
final Triangle midTriangle = triangle.divide(radius); | |
final Triangle[] triangles = { | |
new Triangle(triangle.v1, midTriangle.v1, midTriangle.v3), | |
new Triangle(midTriangle.v1, triangle.v2, midTriangle.v2), | |
new Triangle(midTriangle.v3, midTriangle.v2, triangle.v3), | |
midTriangle}; | |
for (Triangle t : triangles) { | |
addPoints(t, count + 1, radius, index); | |
} | |
} else { | |
_spheres[index].points.add(new Point(triangle)); | |
} | |
} | |
void draw() { | |
background(0); | |
push(); | |
translate(width / 2, height / 2); | |
lights(); | |
directionalLight(0, 0, 1000, -1, 1, -1); | |
//ambientLight(80); | |
rotateX(INIT_ROTATION.x + frameCount / 300.0); | |
rotateY(INIT_ROTATION.y + frameCount / 100.0); | |
rotateZ(INIT_ROTATION.z + frameCount / 200.0); | |
int c = 0; | |
final int freq = 4; | |
final int d = 4; | |
final float threshold = 0.5; | |
for (final Sphere sphere : _spheres) { | |
for (final Point point : sphere.points) { | |
final PVector v = P5Vector.mult(NOISE_RANGE, point.center).div(MAX_SPHERE_RADIUS).add(INIT_NOISE); | |
final float f = noise(v.x, v.y, v.z + NOISE_STEP * frameCount); | |
final float noiseValue = pow(sin(freq * TWO_PI * f), d); | |
final float ratio = (noiseValue - threshold) / (1 - threshold); | |
if (threshold < noiseValue) { | |
fill(sphere.hue, 80, 100); | |
push(); | |
rotateZ(HALF_PI); | |
rotateX(-point.rotation.x); | |
rotateZ(point.rotation.z); | |
translate(0, -sphere.radius, 0); | |
sphere(SPHERE_RADIUS * ratio); | |
pop(); | |
c++; | |
} | |
} | |
} | |
pop(); | |
text(" fps: " + frameRate, 20, 20); | |
text("count: " + c, 20, 40); | |
} | |
class Triangle { | |
final PVector v1; | |
final PVector v2; | |
final PVector v3; | |
Triangle(final PVector v1, final PVector v2, final PVector v3) { | |
this.v1 = v1; | |
this.v2 = v2; | |
this.v3 = v3; | |
} | |
Triangle(final float x1, final float y1, final float z1, final float x2, final float y2, final float z2, final float x3, final float y3, final float z3) { | |
this(new PVector(x1, y1, z1), new PVector(x2, y2, z2), new PVector(x3, y3, z3)); | |
} | |
Triangle divide(final float radius) { | |
final PVector mid12 = PVector.lerp(this.v1, this.v2, 0.5); | |
final PVector mid23 = PVector.lerp(this.v2, this.v3, 0.5); | |
final PVector mid31 = PVector.lerp(this.v3, this.v1, 0.5); | |
final PVector newv1 = mid12.div(mid12.mag()).mult(radius); | |
final PVector newv2 = mid23.div(mid23.mag()).mult(radius); | |
final PVector newv3 = mid31.div(mid31.mag()).mult(radius); | |
return new Triangle(newv1, newv2, newv3); | |
} | |
} | |
class Sphere { | |
final float radius; | |
final float hue; | |
// 512 = 4^3*8 addPointsのtriangles ^ COUNT_LIMIT(再帰段数) * setupのtriangles | |
final ArrayList<Point> points = new ArrayList<Point>(); | |
Sphere(final float radius, final float hue) { | |
this.radius = radius; | |
this.hue = hue; | |
} | |
} | |
class Point { | |
final PVector center; | |
final PVector rotation; | |
Point(Triangle triangle) { | |
this.center = PVector.add(triangle.v1, triangle.v2).add(triangle.v3).div(3); | |
final PVector copy = this.center.copy(); | |
copy.y = 0; | |
final float x = atan2(this.center.z, this.center.x); | |
final float z = atan2(this.center.y, copy.mag()); | |
this.rotation = new PVector(x, 0, z); // 位置は使う側に合わせた | |
} | |
} | |
static class P5Vector { | |
static PVector mult(final PVector v1, final PVector v2) { | |
return new PVector(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment