Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <iostream>
- #include <iomanip>
- #include <vector>
- #include <cmath>
- #include <typeinfo>
- using namespace std;
- class polytope{ //base
- public:
- vector<polytope> e; //elements
- int dim; //dimension, not required for elements
- //each polytope has [dim+1]-dimensional normal and position. I.e. edge is 1-dimensional but it has 2-dimensional vector and position
- vector<double> nor; //normal, n-vector
- vector<double> pos; //position
- vector<int> set; //sub-set of n-1 polytopes inside this polytope
- double length(){
- double m=0;
- for(int i=0;i<nor.size();i++ ){
- m+=nor[i]*nor[i];
- }
- return sqrt(m);
- }
- void normalize(){
- double m=length();
- if(m!=0){
- for(int i=0;i<nor.size();i++ ){
- nor[i]/=m;
- }
- }else if(m==0){//length 0
- nor[0]=1;
- for(int i=1;i<nor.size();i++ ){
- nor[i]=0;
- }
- }
- }
- void echoInfo( int vdecimals = 2 ){
- cout << setprecision(vdecimals) << fixed;
- //base
- if(dim || dim==0 ){
- cout << "\nDim: " << dim << "\n";
- }else if( e.size()!=0 ){
- cout << "\nDim not set!\n";
- }else{
- cout << "\nElement info";
- }
- if( e.size()!=0 ){
- cout << "Element count: " << e.size() << "\n";
- }
- //sub-sets
- cout << "BOF Sub-Sets Info\n";
- int h=0;
- for(polytope i : e ){
- cout << " e[" << h << "]: \n"; h++;
- //set info
- if( i.set.size() > 0 ){
- cout << " sub-set["<<i.set.size()<<"]: [ ";
- for( int j : i.set ){
- cout << j << " ";
- }
- cout << "]\n";
- }
- //nor info
- if( i.nor.size() > 0 ){
- cout << " nor["<<i.nor.size()<<"]: [ ";
- for( double j : i.nor ){
- cout << j << " ";
- }
- cout << "]\n";
- }
- //pos info
- if( i.pos.size() > 0 ){
- cout << " pos["<<i.pos.size()<<"]: [ ";
- for( double j : i.pos ){
- cout << j << " ";
- }
- cout << "]\n";
- }
- }
- cout << "EOF Sub-Sets Info\n";
- }
- };
- //N pool = current working pool : (polytope sp)
- //N-1 pool = Elements in sub-set : (polytope tp)
- //
- //reduce N pool to N-1 dimension
- //This is done by applying N pool transforms to all elements in N pool.set
- polytope redpo( const polytope sp, const polytope tp ){
- polytope redu; //reduced pool
- redu.dim=sp.dim-1;
- //element count in redu
- int re=-1;
- //loop through each sub-set of elements
- for( polytope i : sp.e ) {//elements
- for( int j : i.set ){ //sub-sets
- //get sub-set element that N-pool is pointing
- redu.e.push_back( tp.e[j] );
- re++;
- if( sp.dim>1 ){//faces and higher
- //apply nor and pos for each dimension
- for( int k=0; k<i.nor.size(); k++ ){//apply normal
- while( redu.e[re].nor.size()-1 < k ){ redu.e[re].nor.push_back(0); } //If value doesn't exist, create it
- //TODO: proper normal combination. Current method merely averages them.
- redu.e[re].nor[k]+=i.nor[k];
- redu.e[re].normalize();
- }
- for( int k=0; k<i.pos.size(); k++ ){//apply position
- while( redu.e[re].pos.size()-1 < k ){ redu.e[re].pos.push_back(0); } //-||-
- redu.e[re].pos[k]+=i.pos[k];
- }
- }else if( sp.dim==1 ){//edges to vertices
- for( int k=0; k<i.nor.size(); k++ ){//apply normal
- if(tp.e[j].pos[0]){//if not null
- while( redu.e[re].pos.size()-1 < k ){ redu.e[re].pos.push_back( tp.e[j].pos[0] ); } //copy vertex position to higher dimensions so it can be applied to n-normals
- }else{//if pos[0] null
- while( redu.e[re].pos.size()-1 < k ){ redu.e[re].pos.push_back(0); }
- }
- redu.e[re].pos[k]*=i.nor[k];
- }
- for( int k=0; k<i.pos.size(); k++ ){//apply pos
- if(tp.e[j].pos[0]){//if not null
- while( redu.e[re].pos.size()-1 < k ){ redu.e[re].pos.push_back( tp.e[j].pos[0] ); } //-||-
- }else{//if pos[0] null
- while( redu.e[re].pos.size()-1 < k ){ redu.e[re].pos.push_back(0); }
- }
- redu.e[re].pos[k]+=i.pos[k];
- }
- }
- }
- }
- return redu;
- }
- class object{
- public:
- vector<double> pos; //position
- vector<double> nor; //normal
- vector<polytope> u; //polytope pools
- };
- int main(int ac, char** av){
- object obj;
- //vertex pool
- obj.u.push_back({});
- obj.u[0].dim=0;
- //create 2 vertices
- for(int i=0;i<2;i++){
- obj.u[0].e.push_back({});
- }
- obj.u[0].e[0].pos.push_back( 0.0 );
- obj.u[0].e[1].pos.push_back( 1.0 );
- //edge pool
- obj.u.push_back({});
- obj.u[1].dim=1;
- //create 2 edges
- for(int i=0;i<2;i++){
- obj.u[1].e.push_back({});
- obj.u[1].e[i].set.push_back( 0 );
- obj.u[1].e[i].set.push_back( 1 );
- }
- //right angle
- //transform edges
- //position edge0
- obj.u[1].e[0].pos.push_back( 0.0 );
- obj.u[1].e[0].pos.push_back( 0.0 );
- //vector edge0
- obj.u[1].e[0].nor.push_back( 1.0 );
- obj.u[1].e[0].nor.push_back( 0.0 );
- obj.u[1].e[0].normalize();
- //position edge1
- obj.u[1].e[1].pos.push_back( 1.0 );
- obj.u[1].e[1].pos.push_back( 0.0 );
- //vector edge1
- obj.u[1].e[1].nor.push_back( 0.0 );
- obj.u[1].e[1].nor.push_back( 1.0 );
- obj.u[1].e[1].normalize();
- //face pool
- obj.u.push_back({});
- obj.u[2].dim=2;
- //create face0
- obj.u[2].e.push_back({});
- obj.u[2].e[0].set.push_back( 0 );
- obj.u[2].e[0].set.push_back( 1 );
- //vector face0
- obj.u[2].e[0].nor.push_back( 0.0 );
- obj.u[2].e[0].nor.push_back( 0.0 );
- obj.u[2].e[0].nor.push_back( 1.0 ); //face z+
- obj.u[2].e[0].normalize();
- //position face0
- obj.u[2].e[0].pos.push_back( 0.0 );
- obj.u[2].e[0].pos.push_back( 0.0 );
- obj.u[2].e[0].pos.push_back( 0.0 );
- obj.u[2].echoInfo();
- polytope out = redpo( obj.u[2], obj.u[1] );
- out.dim=1;
- out.echoInfo();
- out = redpo( out, obj.u[0] );
- out.dim=0;
- out.echoInfo();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement