function force_pyramide(p1, p2, p3, rel) { // (0, 0, 0) // rel - var volume = (1/6) * triple_product(p1, p2, p3); // if (volume == 0) return new vector3(0, 0, 0); if (!rel) rel = 0.01; var p0 = middleVector(p1, p2, p3); // var len = p0.length(); var per = perimeter(p1, p2, p3); // var tan_per = per / len; var error = 0.015 * sqr(tan_per); // if (error > rel) { var p12 = middleVector(p1, p2); var p13 = middleVector(p1, p3); var p23 = middleVector(p2, p3); return sumVector( force_pyramide(p1, p12, p13, rel), force_pyramide(p2, p23, p12, rel), force_pyramide(p3, p13, p23, rel), force_pyramide(p12, p23, p13, rel) ); } var ratio = 3 * volume * Math.pow(len, -3); return new vector3(p0.x, p0.y, p0.z).multiplyScalar(ratio); }
function force_object(p0, obj, rel) { var result = new vector3(0, 0, 0); for (var i = 0; i < obj.faces.length; i++) { p1 = subVectors(obj.vertices[obj.faces[i][0] - 1], p0); p2 = subVectors(obj.vertices[obj.faces[i][1] - 1], p0); p3 = subVectors(obj.vertices[obj.faces[i][2] - 1], p0); var f = force_pyramide(p1, p2, p3, rel); result = addVectors(result, f); } return result; }
var rel = 0.01; // var scale = 1000; // , var grav_ratio = 6.672e-11 * 1.0e+13 / (sqr(scale) * volume); // 1+13 var omega2 = sqr(2 * Math.PI / (12.4 * 3600)); // 12,4 function computeGrav() { info.innerHTML = ': ' + (100 * item / object3d.vertices.length).toFixed() + '%'; for (var i = 0; i < 50; i++) { var p0 = object3d.vertices[item]; grav_force[item] = force_object(p0, object3d, rel).multiplyScalar(grav_ratio); // circular_force[item] = new vector3(omega2 * p0.x * scale, omega2 * p0.y * scale, 0); // , z abs_grav_force[item] = grav_force[item].length(); abs_circular_force[item] = circular_force[item].length(); item++; if (item >= object3d.vertices.length) { console.timeEnd('gravity calculate'); clearInterval(timerId); accelSelect(); init(); animate(); break; } } } var item = 0; console.time('gravity calculate'); var timerId = setInterval(computeGrav, 1);
var obj = { vertices: [], normals: [], faces: [] };
function objLoad(url) { var result; var xhr = new XMLHttpRequest(); xhr.open('GET', url, false); xhr.onreadystatechange = function(){ if (xhr.readyState != 4) return; if (xhr.status != 200) { result = xhr.status + ': ' + xhr.statusText + ': ' + xhr.responseText; } else { result = xhr; } } xhr.send(null); return result; } function objParse(url) { var txt = objLoad(url).responseText; var lines = txt.split('\n'); var result; // v float float float var vertex_pattern = /v( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)/; // f vertex vertex vertex ... var face_pattern1 = /f( +-?\d+)( +-?\d+)( +-?\d+)( +-?\d+)?/; // f vertex/uv vertex/uv vertex/uv ... var face_pattern2 = /f( +(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+))?/; // f vertex/uv/normal vertex/uv/normal vertex/uv/normal ... var face_pattern3 = /f( +(-?\d+)\/(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+)\/(-?\d+))?/; // f vertex//normal vertex//normal vertex//normal ... var face_pattern4 = /f( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))?/; var obj = { vertices: [], normals: [], faces: [] }; for (var i = 0; i < lines.length; i++) { var line = lines[i].trim(); if ((result = vertex_pattern.exec(line)) !== null) { obj.vertices.push(new vector3( parseFloat(result[1]), parseFloat(result[2]), parseFloat(result[3]) )); }else if ((result = face_pattern1.exec(line)) !== null) { obj.faces.push([ parseInt(result[1]), parseInt(result[2]), parseInt(result[3]) ]); if (result[4]) obj.faces.push([ parseInt(result[1]), parseInt(result[3]), parseInt(result[4]) ]); }else if ((result = face_pattern2.exec(line)) !== null) { obj.faces.push([ parseInt(result[2]), parseInt(result[5]), parseInt(result[8]) ]); if (result[11]) obj.faces.push([ parseInt(result[2]), parseInt(result[8]), parseInt(result[11]) ]); }else if ((result = face_pattern3.exec(line)) !== null) { obj.faces.push([ parseInt(result[2]), parseInt(result[6]), parseInt(result[10]) ]); if (result[14]) obj.faces.push([ parseInt(result[2]), parseInt(result[10]), parseInt(result[14]) ]); }else if ((result = face_pattern4.exec(line)) !== null) { obj.faces.push([ parseInt(result[2]), parseInt(result[5]), parseInt(result[8]) ]); if (result[11]) obj.faces.push([ parseInt(result[2]), parseInt(result[8]), parseInt(result[11]) ]); } } obj.normals = computeNormalizeNormals(obj); return obj; }
scene = new THREE.Scene();
var fieldWidth = 500; // var fieldHeight = 500; camera = new THREE.PerspectiveCamera(50, fieldWidth / fieldHeight, 0.01, 10000); scene.add(camera); cameraZ = 3 * boundingSphereRadius; // boundingSphereRadius - , camera.position.x = 0; camera.position.y = 0; camera.position.z = cameraZ; camera.lookAt(new THREE.Vector3(0, 0, 0)); //
var ambientLight = new THREE.AmbientLight(0xffffff); scene.add(ambientLight);
renderer = new THREE.WebGLRenderer({antialias: true}); renderer.setClearColor(0xffffff); // renderer.setPixelRatio(window.devicePixelRatio); renderer.setSize(fieldWidth, fieldHeight); // container.appendChild(renderer.domElement); //
var container; var camera, scene, renderer; var axis; var mesh; var boundingSphereRadius, cameraZ; var lines = []; var angleGeneral = 0; function init() { container = document.getElementById('container'); scene = new THREE.Scene(); var fieldWidth = 500; var fieldHeight = 500; camera = new THREE.PerspectiveCamera(50, fieldWidth / fieldHeight, 0.01, 10000); scene.add(camera); var ambientLight = new THREE.AmbientLight(0xffffff); scene.add(ambientLight); loadModel(); cameraZ = 3 * boundingSphereRadius; camera.position.x = 0; camera.position.y = 0; camera.position.z = cameraZ; camera.lookAt(new THREE.Vector3(0, 0, 0)); axis = new THREE.Vector3(0.6, 0.8, 0); // renderer = new THREE.WebGLRenderer({antialias: true}); renderer.setClearColor(0xffffff); renderer.setPixelRatio(window.devicePixelRatio); renderer.setSize(fieldWidth, fieldHeight); container.appendChild(renderer.domElement); }
var geometry = new THREE.BufferGeometry();
var material = new THREE.MeshLambertMaterial( { side: THREE.FrontSide, // vertexColors: THREE.VertexColors // });
var vertices = new Float32Array(9 * object3d.faces.length); for (var i = 0; i < object3d.faces.length; i++) { for (var j = 0; j < 3; j++) { vertices[9*i + 3*j ] = object3d.vertices[object3d.faces[i][j] - 1].x; vertices[9*i + 3*j + 1] = object3d.vertices[object3d.faces[i][j] - 1].y; vertices[9*i + 3*j + 2] = object3d.vertices[object3d.faces[i][j] - 1].z; } } geometry.addAttribute('position', new THREE.BufferAttribute(vertices, 3));
var colors = addColor(); geometry.addAttribute('color', new THREE.BufferAttribute(colors, 3)); function addColor() { var colorMin = [0.0, 0.6, 1.0]; // var colorMax = [1.0, 0.0, 0.0]; // var colors = new Float32Array(9 * object3d.faces.length); for (var i = 0; i < object3d.faces.length; i++) { for (var j = 0; j < 3; j++) { var intensity = (abs_force[object3d.faces[i][j] - 1] - forceMin) / (forceMax - forceMin); colors[9*i + 3*j ] = colorMin[0] + (colorMax[0] - colorMin[0]) * intensity; colors[9*i + 3*j + 1] = colorMin[1] + (colorMax[1] - colorMin[1]) * intensity; colors[9*i + 3*j + 2] = colorMin[2] + (colorMax[2] - colorMin[2]) * intensity; } } return colors; }
var lines; function addLines() { lines = new Array(); for (var i = 0; i < object3d.vertices.length; i++) { var color; var ratio; if (angle_force[i] < 90) { color = 0x000000; // ratio = -0.2 * boundingSphereRadius / forceMax; } else { color = 0xdddddd; // ratio = 0.2 * boundingSphereRadius / forceMax; } var material = new THREE.LineBasicMaterial({ color: color }); var geometry = new THREE.Geometry(); var point1 = object3d.vertices[i]; var point2 = new THREE.Vector3(); point2.copy(force[i]); point2.addVectors(point1, point2.multiplyScalar(ratio)); geometry.vertices.push( new THREE.Vector3(point1.x, point1.y, point1.z), new THREE.Vector3(point2.x, point2.y, point2.z) ); var line = new THREE.Line(geometry, material); rotateAroundWorldAxis(line, axis, angleGeneral); if (hair.checked) scene.add(line); lines.push(line); } }
Source: https://habr.com/ru/post/271451/
All Articles