Advertisement
Guest User

Untitled

a guest
Jul 2nd, 2017
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
BibTeX 8.68 KB | None | 0 0
  1. import  graph3;
  2. struct reper {
  3.    triple o,i,j,k;
  4.    guide3 oi,oj,ok;
  5.    string olabel,ilabel,jlabel,klabel,labelsize;
  6.    
  7.    transform3 trans;
  8.    
  9.    void update_axis() {
  10.        this.oi = this.o -- this.o+this.i;
  11.        this.oj = this.o -- this.o+this.j;
  12.        this.ok = this.o -- this.o+this.k;
  13.    }
  14.    
  15.    void rotate(real alpha,triple u) {
  16.     this.o = three.rotate(alpha,u)*this.o;
  17.        this.i = three.rotate(alpha,u)*this.i;
  18.        this.j = three.rotate(alpha,u)*this.j;
  19.        this.k = three.rotate(alpha,u)*this.k;
  20.        trans = three.rotate(alpha,u) * trans;
  21.        this.update_axis();
  22.    }
  23.    
  24.    void operator init(triple o=(0,0,0),triple i=(1,0,0),triple k=(0,0,1),
  25.                       triple j=(0,1,0),string ilabel="\vec{i}",
  26.                       string jlabel="\vec{j}",string klabel="\vec{k}",
  27.                       string olabel="o",string labelsize="\footnotesize"){
  28.        this.o = o; this.i = i; this.j = j; this.k = k;
  29.        this.update_axis();
  30.        this.olabel = olabel; this.ilabel = ilabel;
  31.        this.jlabel = jlabel; this.klabel = klabel;
  32.        this.labelsize = labelsize;
  33.        
  34.        trans = identity4;
  35.        
  36.        this.rotate(90, this.i);
  37.    }
  38.    
  39.    void shift(triple dxyz) {
  40.        this.o += dxyz;
  41.        trans = three.shift(dxyz)*  trans;
  42.        this.update_axis();
  43.    }
  44.    
  45.  
  46.    void draw(triple view_point) {
  47.        draw(this.oi,red,Arrow3);
  48.        draw(this.oj,red,Arrow3);
  49.        draw(this.ok,red,Arrow3);    
  50.        
  51.        real dij = dot(view_point-this.o,cross(this.i,this.j));
  52.        triple shift_o = unit(this.i+this.j);
  53.        if (dij<0) { shift_o = - shift_o; }
  54.        label(this.labelsize+" $"+this.olabel+"$",this.o,shift_o,blue);
  55.  
  56.        triple shift_i = cross(this.i,view_point-this.o);
  57.        shift_i = unit(shift_i);
  58.        label(this.labelsize+" $"+this.ilabel+"$",this.o+this.i/2,shift_i,blue);
  59.            
  60.        triple shift_j = cross(this.j,view_point-this.o);
  61.        shift_j = unit(shift_j);
  62.        label(this.labelsize+" $"+this.jlabel+"$",this.o+this.j/2,shift_j,blue);
  63.  
  64.        triple shift_k = cross(this.k,view_point-this.o);
  65.        shift_k = unit(shift_k);
  66.        label(this.labelsize+" $"+this.klabel+"$",this.o+this.k/2,shift_k,blue);
  67.    
  68.    }
  69.    
  70.    triple fromModel(triple pt) {
  71.         real[] pp = {pt.x, pt.y, pt.z, 1};
  72.         pp = this.trans*pp;
  73.         return (pp[0], pp[1], pp[2]);
  74.    }
  75.    
  76.    triple toModel(triple pt) {
  77.         real[] pp = {pt.x, pt.y, pt.z, 1};
  78.         pp = inverse(this.trans)*pp;
  79.         return (pp[0], pp[1], pp[2]);
  80.    }
  81. }//Koniec definicji klasy reper
  82.  
  83.  
  84.  
  85. struct frustum {
  86.    reper  ijk;
  87.    real near,far;
  88.    real left,right,down,top,aspect;
  89.    guide3 fface,lface,rface,dface,tface; //nface
  90.    
  91.    void update_faces() {
  92.        triple ldn =  this.left*this.ijk.i+this.down*this.ijk.j-this.near*this.ijk.k;
  93.        triple rdn = this.right*this.ijk.i+this.down*this.ijk.j-this.near*this.ijk.k;
  94.        triple ltn =  this.left*this.ijk.i+ this.top*this.ijk.j-this.near*this.ijk.k;
  95.        triple rtn = this.right*this.ijk.i+ this.top*this.ijk.j-this.near*this.ijk.k;
  96.  
  97.        triple oldn = this.ijk.o+ldn;
  98.        triple ordn = this.ijk.o+rdn;
  99.        triple oltn = this.ijk.o+ltn;
  100.        triple ortn = this.ijk.o+rtn;
  101.        
  102.        real beta = this.far/this.near;
  103.        triple oldf = this.ijk.o+beta*ldn;
  104.        triple ordf = this.ijk.o+beta*rdn;
  105.        triple oltf = this.ijk.o+beta*ltn;
  106.        triple ortf = this.ijk.o+beta*rtn;
  107.  
  108.        this.fface = ordf--oldf--oltf--ortf--cycle;
  109.        this.lface = oldn--oltn--oltf--oldf--cycle;
  110.        this.rface = ordn--ordf--ortf--ortn--cycle;
  111.        this.dface = oldn--oldf--ordf--ordn--cycle;
  112.        this.tface = oltn--ortn--ortf--oltf--cycle;
  113.    }
  114.    
  115.    void operator init(real near=1,real far=10,
  116.                       real left=-1,real right=1, real down=-1,real aspect=1,
  117.                       reper ijk=reper(labelsize="\tiny")){
  118.        this.near = near; this.far = far;
  119.        this.left = left; this.right = right;
  120.        this.down = down; this.aspect = aspect;
  121.        this.top = down+(right-left)/aspect;
  122.        this.ijk = ijk;        
  123.        this.update_faces();
  124.    }
  125.    
  126.    void shift(triple dxyz) {
  127.        this.ijk.shift(dxyz);
  128.        this.update_faces();
  129.    }
  130.    
  131.    void rotate(real alpha,triple u) {
  132.        this.ijk.rotate(alpha,u);
  133.        this.update_faces();
  134.    }
  135.  
  136.    void draw(triple view_point) {
  137.        this.ijk.draw(view_point);
  138.        draw(this.fface);
  139.        //draw(this.nface);
  140.        draw(this.dface);
  141.        draw(this.tface);
  142.        draw(this.lface);
  143.        draw(this.rface);
  144.    }
  145.    
  146.    real[][] frust() {
  147.         real n = this.near;
  148.         real f = this.far;
  149.         real b = this.down;
  150.         real t = this.top;
  151.         real l = this.left;
  152.         real r = this.right;
  153.        
  154.         real[][] a={{2*n / (r-l),           0,  (r+l) / (r-l),              0},
  155.                 {          0, 2*n / (t-b),  (t+b) / (t-b),              0},
  156.             {          0,           0, -(f+n) / (f-n), -2*f*n / (f-n)},
  157.             {          0,           0,             -1,              0}};
  158.  
  159.     return a;
  160.    }
  161.    
  162.    triple toDevice(triple p) {
  163.         real[] pp = { p.x, p.y, p.z, 1 };
  164.         pp = frust()*pp;
  165.         pp /= pp[3];
  166.         return (pp[0], pp[1], pp[2]);
  167.    }
  168.    
  169.    triple fromDevice(triple p) {
  170.         real[] pp = { p.x, p.y, p.z, 1 };
  171.         pp = inverse(frust())*pp;
  172.         pp /= pp[3];
  173.         return (pp[0], pp[1], pp[2]);
  174.    }
  175.    
  176.    // p - punkt we współrzędnych świata
  177.    // zwracany również punkt we współrzędnych świata
  178.    triple project(triple p) {
  179.         // punkt we współrzędnych lokalnych dla związanego repera
  180.         triple lp = this.ijk.toModel(p);
  181.         // punkt we współrzędnych urządzenia
  182.         triple dp = this.toDevice(lp);
  183.         // punkt we współrzędnych urządzenia zrzutowany na near plane (z = -1)
  184.         triple pd = (dp.x, dp.y, -1);
  185.         // zrzutowany punkt we współrzędnych lokalnych
  186.     triple pl = this.fromDevice(pd);
  187.     // zrzutowany punkt we współrzędnych świata
  188.     triple pw = this.ijk.fromModel(pl);
  189.    
  190.     return pw;
  191.    }
  192.    
  193. }//Koniec definicji klasy frustum
  194.  
  195.  
  196. triple ota(triple p) {
  197.     return (p.x, -p.z, p.y);
  198. }
  199.  
  200. triple ota(real x, real y, real z) {
  201.     return (x, -z, y);
  202. }
  203.  
  204. triple ato(triple p) {
  205.     return (p.x, p.z, -p.y);
  206. }
  207.  
  208. triple ato(real x, real y, real z) {
  209.     return (x, z, -y);
  210. }
  211.  
  212. import math;
  213.  
  214.  
  215. settings.outformat="pdf";
  216. settings . prc= false ;
  217. defaultfilename = "reper-2" ;
  218. size3 ( 16cm , 16cm , keepAspect=true) ;
  219. size ( 16cm , 16cm , keepAspect=true) ;
  220. texpreamble("\def\vec#1{\overrightarrow{#1}}");
  221.  
  222.  
  223. triple view_point = (30 , -30 ,30);
  224. currentprojection = perspective ( view_point ) ;
  225.  
  226. //reper r = reper ( labelsize="\tiny" ) ;
  227. //write ( 'o=' , r.o ) ; write ( 'i=' , r.i ) ;
  228. //write ( 'j=' , r.j ) ; write ( 'k=' , r.k ) ;
  229. //r.draw ( view_point ) ;
  230.  
  231. //r.shift ((2 ,0 ,0));
  232. //r.draw ( view_point ) ;
  233.  
  234. //r.shift ((0 ,2 ,0));
  235. //r.rotate (60 , r.k ) ;
  236. //r.draw ( view_point ) ;
  237.  
  238. //triple p1 = (1,0,0);
  239. //dot (p1, blue);
  240. //triple p2 = r.fromModel(p1);
  241. //dot (p2, blue);
  242. //triple p3 = r.toModel(p2);
  243.  
  244. //write('p1=', p1);
  245. //write('p2=', p2);
  246. //write('p3=', p3);
  247.  
  248.  
  249. frustum fr1 = frustum(near=4 , far=15);
  250. fr1.draw ( view_point ) ;
  251.  
  252. frustum fr2 = frustum(near=4 , far=15);
  253. fr2.shift ((6 ,0 ,0));
  254. fr2.rotate (30 , fr2.ijk.k ) ;
  255. fr2.draw (view_point) ;
  256.  
  257.  
  258. triple l1 = (-1, 0, -5);
  259.  
  260.  
  261. /*triple g1 = fr1.ijk.fromModel(l1);
  262. triple g2 = fr2.ijk.fromModel(l1);
  263. dot(g1, blue);
  264. dot(g2, blue);
  265. write('g1=', g1);
  266. write('g2=', g2);*/
  267.  
  268. /*
  269. triple d1 = fr1.toDevice(l1);
  270.  
  271. write('l1=', l1);
  272. write('d1=', d1);
  273.  
  274. triple dp = (d1.x, d1.y, -1);
  275. triple p1 = fr1.fromDevice(dp);
  276. p1 = fr1.ijk.fromModel(p1);*/
  277.  
  278. triple g = (3.3, 14, 1.5);
  279. dot(g, blue);
  280. triple p1 = fr1.project(g);
  281. triple p2 = fr2.project(g);
  282. dot(p1, red);
  283. dot(p2, red);
  284.  
  285. // testy
  286. triple l1 = (-1, -1, -4);
  287. triple g1 = fr1.ijk.fromModel(l1);
  288. dot("$g_1$", g1, green);
  289. triple g2 = fr2.ijk.fromModel(l1);
  290. dot("$g_2$", g2, green);
  291.  
  292. triple d1 = fr2.toDevice(l1);
  293. triple d2 = fr1.fromDevice((1, 1, 1));
  294. triple w2 = fr1.ijk.fromModel(d2);
  295. dot("$d_2$", w2, green);
  296.  
  297. write('We wspolrzednych modelu: l1=', l1);
  298. write('We wspolrzednych globalnych dla fr1: g1=', g1);
  299. write('We wspolrzednych globalnych dla fr2: g2=', g2);
  300. write('g1 to lewy dolny rog frustuma na near plane');
  301. write('Przeliczenie na wspolrzedne urzadzenia');
  302. write('d1 (powinno byc -1, -1, -1): ', d1);
  303. write('Przeliczanie ze wspolrzednych urzadzenia');
  304. write('d2 (powinno byc -3.75, -3.75, -15): ', d2);
  305. write('d2 powinno znajdowac sie w prawym gornym rogu pierwszego frustuma na far plane');
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement