Libero51
| Inviato il: 21/05/2021 04:51:20
|
Vediamo ora come affrontare il tracciamento di una catenaria tra due sospensioni in uno spazio 3d.
Nello spazio 2d le coordinate dei sostegni sono (x1,y1) e (x2,y2).
Nello spazio 3d le coordinate dei sostegni sono (x1,y1,z1) e (x2,y2,z2).
L'altezza tra i sostegni continua ad essere y2-y1.
La distanza orizzontale diventa l'ipotenusa di un triangolo rettangolo in cui i cateti sono (x2-x1) e (z2-z1) ... (Teorema di Pitagora).
Nel programma che vi propongo troverete nella funzione d_par(v1,v2)
le formule della distanza (Pitagora) ed il calcolo dell'angolo orizzontale
tra i sostegni... arcotangente di (z2-z1)/((x2-x1).
La funzione calcola distanza e angolo orizzontale tra i sostegni (v1 e v2)
dove v1 è il vettore (x1,y1,z1) e v2 è il vettore (x2,y2,z2)
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="../BabylonJS/babylon_min.js"></script>
</head>
<body>
<canvas id="renderCanvas" width="1000" height="600"></canvas>
<script>
var canvas = document.getElementById("renderCanvas");
var engine = new BABYLON.Engine(canvas, true,{preserveDrawingBuffer: true, stencil: true });
var $tral=[];
var $tern=[];
var $pall=[];
var $a,$d;
var createScene = function () {
var scene = new BABYLON.Scene(engine);
//scene.ambientColor = new BABYLON.Color3(1, 1, 1);
var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 50, 20), scene);
light.diffuse = new BABYLON.Color3(1, 1, 1);
light.specular = new BABYLON.Color3(1, 1, 1);
light.groundColor = new BABYLON.Color3(1, 1, 1);
var camera = new BABYLON.FreeCamera("camera1",new BABYLON.Vector3(30,.6,-10), scene);
camera.attachControl(canvas, true);
camera.rotation=new BABYLON.Vector3(0,-.8,0);
//----Mesh Traliccio
let tralMat = new BABYLON.StandardMaterial("tralMat",scene);
tralMat.diffuseTexture= new BABYLON.Texture("textures/trali.png", scene);
tralMat.diffuseTexture.hasAlpha = true;
tralMat.backFaceCulling = false;
var positions =[
-2, 10, .1, 2, 10, .1, -2,.85, .5, 2,.85, .5, // 3 Traliccio
-2, 10, -.1, 2, 10, -.1, -2,.85, -.5, 2,.85, -.5, // 7
-.75, 0, .75, .75, 0, .75, -.75,.84, .75, .75,.84, .75, //11 Blocco
-.75,.84,-.75, .75,.84,-.75, -.75, 0,-.75, .75, 0,-.75]; //15
var indices =[
0, 1, 3, 3, 2, 0, 4 , 5, 7, 7, 6, 4, 8, 9,11, 11,10, 8,
10,11,13, 13,12,10, 12 ,13,15, 15,14,12,
14, 8,10, 10,12,14, 9,15,13, 13,11,9];
var uvs =[
0, 1, 1, 1, 0,.087, 1, .087, // 3
0, 1, 1, 1, 0,.087, 1, .087, // 7
.45, .07, .55,.07, .45, 0, .55, 0, //11
.45, .07, .55,.07, .45, 0, .55, 0]; //15
var normals = [];
BABYLON.VertexData.ComputeNormals(positions, indices, normals);
var vertexData = new BABYLON.VertexData();
vertexData.positions = positions;
vertexData.indices = indices;
vertexData.normals = normals;
vertexData.uvs = uvs;
$tral[0]=[];
$tral[0][0] = new BABYLON.Mesh("custom", scene);
vertexData.applyToMesh($tral[0][0]);
//-------------------------------------------------Traliccio 1
$tral[0][0].material=tralMat;
$tral[0][0].position=new BABYLON.Vector3(0,0,0);
$tral[0][0].rotation=new BABYLON.Vector3(0,0,0);
//-------------------------------------------------Traliccio 2
$tral[1]=[];
$tral[1][0]=$tral[0][0].clone();
$tral[1][0].position=new BABYLON.Vector3(0,0,50);
$tral[1][0].rotation=new BABYLON.Vector3(0,0,0);
//-------------------------------------------------Traliccio 3
$tral[2]=[];
$tral[2][0]=$tral[0][0].clone();
$tral[2][0].position=new BABYLON.Vector3(40,20,90);
$tral[2][0].rotation=new BABYLON.Vector3(0,.5,0);
//-------------------------------------------------Traliccio 4
$tral[3]=[];
$tral[3][0]=$tral[0][0].clone();
$tral[3][0].position=new BABYLON.Vector3(40,-20,250);
$tral[3][0].rotation=new BABYLON.Vector3(0,.5,0);
IsoDat();
Terna();
return scene;
};
scene = createScene();
engine.runRenderLoop(function () {
if (scene) {scene.render();}
});
window.addEventListener("resize", function () {engine.resize();});
function IsoDat(){
let a,dt1,dt2,dt3,x1,x2,x3,y1,y2,y3,z1,z2,z3;
for(var k=0;k<$tral.length;k++){
a=-$tral[k][0].rotation.y;
x1=$tral[k][0].position.x-1.22*Math.cos(a);
x2=$tral[k][0].position.x-1.74*Math.cos(a);
x3=$tral[k][0].position.x+1.59*Math.cos(a);
y1=$tral[k][0].position.y+8.4;
y2=$tral[k][0].position.y+6.9;
y3=$tral[k][0].position.y+7.65;
z1=$tral[k][0].position.z-1.22*Math.sin(a);
z2=$tral[k][0].position.z-1.74*Math.sin(a);
z3=$tral[k][0].position.z+1.59*Math.sin(a);
$tral[k][1]=new BABYLON.Vector3(x1,y1,z1);
$tral[k][2]=new BABYLON.Vector3(x2,y2,z2);
$tral[k][3]=new BABYLON.Vector3(x3,y3,z3);
if(k>0){
$tral[k][4]=y1-$tral[k-1][1].y; //h
$tral[k][5]=y2-$tral[k-1][2].y;
$tral[k][6]=y3-$tral[k-1][3].y;
d_par($tral[k-1][1],$tral[k][1]);
$tral[k][7]=$d;$tral[k][10]=$a; // distanza angolo
d_par($tral[k-1][2],$tral[k][2]);
$tral[k][8]=$d;$tral[k][11]=$a;
d_par($tral[k-1][3],$tral[k][3]);
$tral[k][9]=$d;$tral[k][12]=$a;
}
}
}
function Terna(){
for(var k=1;k<$tral.length;k++){
$tern[k]=[];
for(var f=0;f<3;f++){Fase(k,f);}
}
}
function Fase(k,f){
let xk,yk,vx,vz;
let c=[];
let w=10; // spezzate
let p=.003; // coefficiente parabola y= p*x*x
let h=$tral[k][4+k-1]; // dislivello
let d=$tral[k][7+k-1] // distanza
let ds=d/(w); // lunghezza spezzata
let x1=-h/(2*p*d)-d/2; // start su parabola
let y1=p*x1*x1;
let a=$tral[k][10+f]; // angolo orizzontale
let point;
let sfe;
c[0]=$tral[k][1+f]; // start Vector3
for(var j=1;j<(w+1);j++){
vx=ds*Math.cos(a);
vz=ds*Math.sin(a);
xk=x1+j*ds;
yk=y1-p*xk*xk; // ordinata parabola
c[j]= new BABYLON.Vector3(c[j-1].x-vx,c[0].y-yk,c[j-1].z-vz);
point=[c[j-1],c[j]];
$tern[k][1]= BABYLON.MeshBuilder.CreateLines("lines", {points: point});
$tern[k][1].color = new BABYLON.Color3(.2,.1,0);
$tern[k][1].useVertexAlpha=false;
/*
sfe = BABYLON.MeshBuilder.CreateSphere("sphere", {diameter: .2});
sfe.position=c[j];
$pall.push(sfe);
sfe.setEnabled=false;
*/
}
}
function d_par(v1,v2){
let x1,y1,z1,z2;
x1=v1.x;z1=v1.z;
x2=v2.x;z2=v2.z;
$a=Math.atan2(z2-z1,x2-x1); // angolo
$d=Math.sqrt(Math.pow(x2-x1,2)+Math.pow(z2-z1,2)); // distanza
}
</script>
</body>
</html>
Ecco cosa appare ...
![http://www.energialternativa.info/public/newforum/ForumEA/U/Tralicci_EA.png](http://www.energialternativa.info/public/newforum/ForumEA/U/Tralicci_EA.png)
Potete far funzionare il programma qui...LINK
Una cliccata sullo schermo e muovetevi con mouse e tasti freccia...
Vedremo prossimamente come far funzionare il programma in ambito locale...
e magari ... come disegnare un traliccio 3d (semplificato) con soli 16 punti sfruttando il canale alfa (RGBA Red Green Blue Alfa) e usando GIMP.
Saluti
(segue)
Modificato da Libero51 - 21/05/2021, 06:20:53
|