__host__ __device__ flouble operator()(unsigned int threadIdx) { unsigned int seed = thrust_hash(threadIdx) * thrust::get<0>(t); thrust::minstd_rand rng(seed); thrust::random::normal_distribution<flouble> nrm(thrust::get<1>(t), thrust::get<2>(t)); // return nrm(rng); // FIXME shouldn't have to do this, but current normal_distribution is bugged... return thrust::get<1>(t) + thrust::get<2>(t)*nrm(rng); }
Vector3D Vertex::normal( void ) const // TODO Returns an approximate unit normal at this vertex, computed by // TODO taking the area-weighted average of the normals of neighboring // TODO triangles, then normalizing. { // TODO Compute and return the area-weighted unit normal. //no boundary polygon HalfedgeCIter h = this->halfedge(); Vector3D nrm(0, 0, 0); double totalarea = 0; do { h = h->twin(); FaceCIter f = h->face(); if(!f->isBoundary()) { VertexCIter v1 = h->vertex(); VertexCIter v2 = h->next()->twin()->vertex(); Vector3D out = cross(v1->position - position, v2->position - position); nrm += out; totalarea += out.norm(); } h = h->next(); } while(h != this->halfedge()); nrm /= totalarea; nrm.normalize(); return nrm; }
TerrainRenderablePlane::TerrainRenderablePlane(GameEntity* parent): TerrainRenderable(parent) { D3DXVECTOR3 org000(0,0,0); D3DXVECTOR3 nrm(0,1,0); D3DXPlaneFromPointNormal(&m_phy_shape,&org000,&nrm); }
bool Stokhos::StieltjesPCEBasis<ordinal_type, value_type>:: computeRecurrenceCoefficients(ordinal_type n, Teuchos::Array<value_type>& alpha, Teuchos::Array<value_type>& beta, Teuchos::Array<value_type>& delta, Teuchos::Array<value_type>& gamma) const { ordinal_type nqp = phi_vals.size(); Teuchos::Array<value_type> nrm(n); Teuchos::Array< Teuchos::Array<value_type> > vals(nqp); for (ordinal_type i=0; i<nqp; i++) vals[i].resize(n); stieltjes(0, n, pce_weights, pce_vals, alpha, beta, nrm, vals); for (ordinal_type i=0; i<n; i++) { delta[i] = value_type(1.0); gamma[i] = value_type(1.0); } // Save basis functions at quad point values if (n == this->p+1) phi_vals = vals; return false; }
/** * Returns the bitmap representing the untrasformed image */ Bitmap *DWT::toBitmap() { Bitmap *result = new Bitmap(realWidth, realHeight); for (unsigned int i = 0; i < realHeight; i++) { for (unsigned int j = 0; j < realWidth; j++) { result->set(i*realWidth + j, nrm(coeff[i*width + j])); } } return result; }
void Stokhos::StieltjesPCEBasis<ordinal_type, value_type>:: computeRecurrenceCoefficients(ordinal_type n, Teuchos::Array<value_type>& alpha, Teuchos::Array<value_type>& beta, Teuchos::Array<value_type>& delta) const { ordinal_type nqp = phi_vals.size(); Teuchos::Array<value_type> nrm(n); Teuchos::Array< Teuchos::Array<value_type> > vals(nqp); for (ordinal_type i=0; i<nqp; i++) vals[i].resize(n); stieltjes(0, n, pce_weights, pce_vals, alpha, beta, nrm, vals); for (ordinal_type i=0; i<n; i++) delta[i] = value_type(1.0); }
std::string function_algebra_distance::write_code_eval(::std::ostream& out, int& vnum, ::std::string const& var) const { ::std::string r(makename("dist2hyp",vnum++)); ::std::string nrm(makename("n",vnum++)); #ifdef GRAL_HAS_SSTREAM ::std::ostringstream coords; #else ::std::ostrstream coords; #endif coords << normal; int dim = normal.dim(); out << "coord_type " << nrm << "(makepoint(" << dim << "," << '"' << coords.str() << '"' << "));\n" << "double " << r << "( " << nrm << " * " << var << " - " << dist << ");\n"; return r; }
void prox(prob_vars * vars, all_data * data, prox_data * p_data) { double v[data->m*(data->T+1)]; memcpy(v,vars->u,sizeof(double)*data->m*(data->T+1)); subArray(v,vars->y,data->m*(data->T+1)); memcpy(vars->x_t,vars->x,sizeof(double)*data->n*(data->T+1)); subArray(vars->x_t,vars->z,data->n*(data->T+1)); double nm,fac; // #pragma omp parallel for private(nm,fac) for(int i=0;i<data->T+1;i++){ nm = nrm(&v[i*data->m],data->m); fac = 1-fminl(1/(1+data->rho),p_data->M/(data->rho*nm)); for(int j=0;j<data->m;j++){ vars->u_t[i*data->m+j]=fac*v[i*data->m+j]; } } }
int main() { double a[100],b[100],c=100.0; int i=1,j=0; //b[0]=(240*pow(-0.5,4)+18*pow(-0.5,3)+9*pow(-0.5,2)-221*-0.5-9); printf("Enter initial guess:"); scanf("%lf",&a[0]); printf("\n\n The values of iterations are:\n\n "); while(c>0.000000000001) { a[j+1]=nrm(a[j]); c=a[j+1]-a[j]; c=fabs(c); printf("%d\t%.11f\n",j,a[j+1]); j++; } printf("\nThe root of the function is: %.11f",a[j]); }
bool Stokhos::LanczosPCEBasis<ordinal_type, value_type>:: computeRecurrenceCoefficients(ordinal_type n, Teuchos::Array<value_type>& alpha, Teuchos::Array<value_type>& beta, Teuchos::Array<value_type>& delta, Teuchos::Array<value_type>& gamma) const { Teuchos::Array<value_type> nrm(n); vectorspace_type vs(pce_weights); operator_type A(pce_vals); // Create space to store lanczos vectors -- use lanczos_vecs if // we are requesting p+1 vectors Teuchos::RCP<matrix_type> lv; if (n == this->p+1) lv = Teuchos::rcp(&lanczos_vecs, false); else lv = Teuchos::rcp(new matrix_type(nqp,n)); if (this->normalize) lanczos_type::computeNormalized(n, vs, A, u0, *lv, alpha, beta, nrm); else lanczos_type::compute(n, vs, A, u0, *lv, alpha, beta, nrm); for (ordinal_type i=0; i<n; i++) { delta[i] = value_type(1.0); } if (this->normalize) gamma = beta; else for (ordinal_type i=0; i<n; i++) gamma[i] = value_type(1.0); return this->normalize; }
osg::Geometry* makePols(void) { tessellateDemoGeometry *gtess = new tessellateDemoGeometry; int i; osg::Vec3Array *coords = new osg::Vec3Array; osg::Vec3Array *nrms = new osg::Vec3Array; osg::Vec2Array *tcs = new osg::Vec2Array; osg::Vec3 nrm(0, -1, 0); // coordinates from red book code but shifted by 1000 & 2000 for alternate Tessellatory things. static GLdouble rects[12][3] = { { 50.0, 50.0, 0.0 }, { 300.0, 50.0, 0.0 }, { 300.0, 300.0, 0.0 }, { 50.0, 300.0, 0.0 }, { 100.0, 100.0, 0.0 }, { 250.0, 100.0, 0.0 }, { 250.0, 250.0, 0.0 }, { 100.0, 250.0, 0.0 }, { 150.0, 150.0, 0.0 }, { 200.0, 150.0, 0.0 }, { 200.0, 200.0, 0.0 }, { 150.0, 200.0, 0.0 } }; static GLdouble rectsMidanti[12][3] = // the centre 2 contours are traversed opposite order to outer contour. { { 1050.0, 50.0, 0.0 }, { 1300.0, 50.0, 0.0 }, { 1300.0, 300.0, 0.0 }, { 1050.0, 300.0, 0.0 }, { 1250.0, 100.0, 0.0 }, { 1100.0, 100.0, 0.0 }, { 1100.0, 250.0, 0.0 }, { 1250.0, 250.0, 0.0 }, { 1200.0, 150.0, 0.0 }, { 1150.0, 150.0, 0.0 }, { 1150.0, 200.0, 0.0 }, { 1200.0, 200.0, 0.0 } }; static GLdouble spiral[16][3] = // shift by 1000; nb the order of vertices is reversed from that of the red book { { 3400.0, 250.0, 0.0 }, { 3400.0, 50.0, 0.0 }, { 3050.0, 50.0, 0.0 }, { 3050.0, 400.0, 0.0 }, { 3350.0, 400.0, 0.0 }, { 3350.0, 100.0, 0.0 }, { 3100.0, 100.0, 0.0 }, { 3100.0, 350.0, 0.0 }, { 3300.0, 350.0, 0.0 }, { 3300.0, 150.0, 0.0 }, { 3150.0, 150.0, 0.0 }, { 3150.0, 300.0, 0.0 }, { 3250.0, 300.0, 0.0 }, { 3250.0, 200.0, 0.0 }, { 3200.0, 200.0, 0.0 }, { 3200.0, 250.0, 0.0 } }; static GLdouble quad1[4][3] = // shift by 2000 for next 3 things { { 2050.0, 150.0, 0.0 }, { 2350.0, 150.0, 0.0 }, { 2350.0, 200.0, 0.0 }, { 2050.0, 200.0, 0.0 } }; static GLdouble quad2[4][3] = { { 2100.0, 100.0, 0.0 }, { 2300.0, 100.0, 0.0 }, { 2300.0, 350.0, 0.0 }, { 2100.0, 350.0, 0.0 } }; static GLdouble tri[3][3] = { { 2200.0, 50.0, 0.0 }, { 2250.0, 300.0, 0.0 }, { 2150.0, 300.0, 0.0 } }; static GLdouble quad3[4][3] = { { 100.0, 1100.0, 0.0 }, { 1300.0, 1100.0, 0.0 }, { 1300.0, 2350.0, 0.0 }, { 100.0, 2350.0, 0.0} }; static GLdouble quadstrip[8][3] = { { 900.0, 1130.0, 0.0 }, { 1100.0, 1130.0, 0.0 }, { 900.0, 1350.0, 0.0 }, { 950.0, 1350.0, 0.0 }, { 900.0, 1550.0, 0.0 }, { 1000.0, 1550.0, 0.0 }, { 900.0, 1750.0, 0.0 }, { 1400.0, 1750.0, 0.0 } }; for (i = 0; i < 12; i++) { coords->push_back(osg::Vec3(rects[i][0], rects[i][2], rects[i][1])); tcs->push_back(osg::Vec2(rects[i][0], rects[i][1]) / 200.0); nrms->push_back(nrm); } for (i = 0; i < 12; i++) { coords->push_back(osg::Vec3(rectsMidanti[i][0], rectsMidanti[i][2], rectsMidanti[i][1])); tcs->push_back(osg::Vec2(rectsMidanti[i][0], rectsMidanti[i][1]) / 200.0); nrms->push_back(nrm); } for (i = 0; i < 16; i++) // and reverse spiral to make same as that of red book ch 11 { coords->push_back(osg::Vec3(spiral[15 - i][0], spiral[15 - i][2], spiral[15 - i][1])); tcs->push_back(osg::Vec2(spiral[15 - i][0], spiral[15 - i][1]) / 200.0); nrms->push_back(nrm); } for (i = 0; i < 4; i++) { coords->push_back(osg::Vec3(quad1[i][0], quad1[i][2], quad1[i][1])); tcs->push_back(osg::Vec2(quad1[i][0], quad1[i][1]) / 200.0); nrms->push_back(nrm); } for (i = 0; i < 4; i++) { coords->push_back(osg::Vec3(quad2[i][0], quad2[i][2], quad2[i][1])); tcs->push_back(osg::Vec2(quad2[i][0], quad2[i][1]) / 200.0); nrms->push_back(nrm); } for (i = 0; i < 3; i++) { coords->push_back(osg::Vec3(tri[i][0], tri[i][2], tri[i][1])); tcs->push_back(osg::Vec2(tri[i][0], tri[i][1]) / 200.0); nrms->push_back(nrm); } // add one large quad with multiple holes for (i = 0; i < 4; i++) { coords->push_back(osg::Vec3(quad3[i][0], quad3[i][2], quad3[i][1])); tcs->push_back(osg::Vec2(quad3[i][0], quad3[i][1]) / 200.0); nrms->push_back(nrm); } { osg::Vec3 centre(300, 0, 1500); for (i = 0; i < 18; i++) { osg::Vec3 rim = centre + osg::Vec3(-cos(osg::DegreesToRadians((float)i * 20.0)), 0.0, sin(osg::DegreesToRadians((float)i * 20.0))) * 150.0; coords->push_back(rim); tcs->push_back(osg::Vec2(rim.x(), rim.z()) / 200.0); nrms->push_back(nrm); } } { osg::Vec3 centre(400, 0, 1800); for (i = 0; i < 18; i++) { osg::Vec3 rim = centre + osg::Vec3(-cos(osg::DegreesToRadians((float)i * 15.0)), 0.0, sin(osg::DegreesToRadians((float)i * 15.0))) * 250.0; coords->push_back(rim); tcs->push_back(osg::Vec2(rim.x(), rim.z()) / 200.0); nrms->push_back(nrm); } } { osg::Vec3 centre(600, 0, 1400); for (i = 0; i < 18; i++) { osg::Vec3 rim = centre + osg::Vec3(-cos(osg::DegreesToRadians((float)i * 12.0)), 0.0, sin(osg::DegreesToRadians((float)i * 12.0))) * 250.0; coords->push_back(rim); tcs->push_back(osg::Vec2(rim.x(), rim.z()) / 200.0); nrms->push_back(nrm); } } // add one large quadstrip for (i = 0; i < 8; i++) { coords->push_back(osg::Vec3(quadstrip[i][0], quadstrip[i][2], quadstrip[i][1])); tcs->push_back(osg::Vec2(quadstrip[i][0], quadstrip[i][1]) / 200.0); nrms->push_back(nrm); } gtess->setVertexArray(coords); gtess->setNormalArray(nrms, osg::Array::BIND_PER_VERTEX); gtess->setTexCoordArray(0, tcs); // demonstrate that the Tessellator makes textured tessellations osg::StateSet *stateset = new osg::StateSet(); osg::Image *image = osgDB::readImageFile("Cubemap_snow/posz.jpg"); if (image) { osg::Texture2D *texture = new osg::Texture2D; texture->setImage(image); texture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::REPEAT); texture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::REPEAT); stateset->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON); } gtess->setStateSet(stateset); int nstart = 0; // the contours accepoted are polygons; quads & tris. Trifans can bve added later. gtess->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, nstart, 12)); nstart += 12; gtess->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, nstart, 12)); nstart += 12; gtess->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POLYGON, nstart, 16)); nstart += 16; gtess->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, nstart, 4)); nstart += 4; gtess->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, nstart, 4)); nstart += 4; gtess->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES, nstart, 3)); nstart += 3; // A rectabngle with multiple holes gtess->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_LOOP, nstart, 4)); nstart += 4; gtess->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_FAN, nstart, 18)); nstart += 18; gtess->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POLYGON, nstart, 18)); nstart += 18; gtess->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POLYGON, nstart, 18)); nstart += 18; // test for quad strip gtess->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_STRIP, nstart, 8)); nstart += 8; // We need to access the tessellatable contours again to demonstrate all types of tessellation. // I could add the Tessellator to the geometry as userdata, but here // I use the derived tessellateDemoGeometry to hold both the drawable geode and the original contours. gtess->setTessellationType(osgUtil::Tessellator::TESS_TYPE_GEOMETRY); gtess->setBoundaryOnly(true); gtess->setWindingType(osgUtil::Tessellator::TESS_WINDING_ABS_GEQ_TWO); // so that first change in wind type makes the commonest tessellation - ODD. return gtess; }
osg::Geometry* makeSideWall(const float xpos) { // demonstrate making a rectangular 'wall' with 2 holes in it. osg::Geometry *gtess = new osg::Geometry; int i; osg::Vec3Array *coords = new osg::Vec3Array; osg::Vec3Array *nrms = new osg::Vec3Array; osg::Vec2Array *tcs = new osg::Vec2Array; osg::Vec3 nrm(-1, 0, 0); // front wall static GLdouble wall[4][2] = { { 1130.0, 0.0 }, { 1130.0, 300.0 }, { 1340.0, 300.0 }, { 1340.0, 0.0 } }; gtess->setVertexArray(coords); gtess->setNormalArray(nrms, osg::Array::BIND_PER_VERTEX); gtess->setTexCoordArray(0, tcs); for (i = 0; i < 4; i++) { coords->push_back(osg::Vec3(xpos, wall[i][1], wall[i][0])); tcs->push_back(osg::Vec2(wall[i][1], wall[i][0]) / 100.0); nrms->push_back(nrm); } int nstart = 0; gtess->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, nstart, 4)); nstart += 4; for (i = 0; i < 24; i++) // make an ellipse hole { float y = 150 + 50 * cos(i * 2 * osg::PI / 24.0); float z = 1300 + 30 * sin(i * 2 * osg::PI / 24.0); coords->push_back(osg::Vec3(xpos, y, z)); tcs->push_back(osg::Vec2(y, z) / 100.0); nrms->push_back(nrm); } gtess->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POLYGON, nstart, 24)); nstart += 24; for (i = 0; i < 5; i++) // make a pentagonal hole { float y = 150 + 50 * cos(i * 2 * osg::PI / 5.0); float z = 1200 + 40 * sin(i * 2 * osg::PI / 5.0); coords->push_back(osg::Vec3(xpos, y, z)); tcs->push_back(osg::Vec2(y, z) / 100.0); nrms->push_back(nrm); } gtess->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POLYGON, nstart, 5)); nstart += 5; // demonstrate that the Tessellator makes textured tessellations osg::StateSet *stateset = new osg::StateSet(); osg::Image *image = osgDB::readImageFile("Cubemap_snow/posx.jpg"); if (image) { osg::Texture2D *texture = new osg::Texture2D; texture->setImage(image); texture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::REPEAT); texture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::REPEAT); stateset->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON); } gtess->setStateSet(stateset); osg::ref_ptr<osgUtil::Tessellator> tscx = new osgUtil::Tessellator; // the v1.2 multi-contour Tessellator. // we use the geometry primitives to describe the contours which are tessellated. // Winding odd means leave hole in surface where there are 2,4,6... contours circling the point. tscx->setTessellationType(osgUtil::Tessellator::TESS_TYPE_GEOMETRY); tscx->setBoundaryOnly(false); tscx->setWindingType(osgUtil::Tessellator::TESS_WINDING_ODD); // so that first change in wind type makes the commonest tessellation - ODD. tscx->retessellatePolygons(*gtess); return gtess; }
osg::Geometry* makeFrontWall(const float zpos) { // an example of using one tessellation to make a 'house' wall // describe the wall as a pentagon, then door & 4 windows are further contours // tessellate the set of contours to make a 'house wall' from the Boolean-like operations. int nstart = 0; // counts vertices used for the geometry primitives osg::Geometry *gtess = new osg::Geometry; int i; osg::Vec3Array *coords = new osg::Vec3Array; osg::Vec3Array *nrms = new osg::Vec3Array; osg::Vec2Array *tcs = new osg::Vec2Array; osg::Vec3 nrm(0, -1, 0); // front wall static GLdouble wall[5][2] = { { 2200.0, 1130.0 }, { 2600.0, 1130.0 }, { 2600.0, 1340.0 }, { 2400.0, 1440.0 }, { 2200.0, 1340.0 } }; static GLdouble door[4][2] = { { 2360.0, 1130.0 }, { 2440.0, 1130.0 }, { 2440.0, 1230.0 }, { 2360.0, 1230.0 } }; static GLdouble windows[16][2] = { { 2240.0, 1180.0 }, { 2330.0, 1180.0 }, { 2330.0, 1220.0 }, { 2240.0, 1220.0 }, { 2460.0, 1180.0 }, { 2560.0, 1180.0 }, { 2560.0, 1220.0 }, { 2460.0, 1220.0 }, { 2240.0, 1280.0 }, { 2330.0, 1280.0 }, { 2330.0, 1320.0 }, { 2240.0, 1320.0 }, { 2460.0, 1280.0 }, { 2560.0, 1280.0 }, { 2560.0, 1320.0 }, { 2460.0, 1320.0 } }; gtess->setVertexArray(coords); gtess->setNormalArray(nrms, osg::Array::BIND_PER_VERTEX); gtess->setTexCoordArray(0, tcs); // add one large pentagon -the wall for (i = 0; i < 5; i++) { coords->push_back(osg::Vec3(wall[i][0], zpos, wall[i][1])); tcs->push_back(osg::Vec2(wall[i][0], wall[i][1]) / 100.0); nrms->push_back(nrm); } gtess->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POLYGON, nstart, 5)); nstart += 5; // add first hole, a door for (i = 0; i < 4; i++) { coords->push_back(osg::Vec3(door[i][0], zpos, door[i][1])); tcs->push_back(osg::Vec2(door[i][0], door[i][1]) / 100.0); nrms->push_back(nrm); } // and windows for (i = 0; i < 16; i++) { coords->push_back(osg::Vec3(windows[i][0], zpos, windows[i][1])); tcs->push_back(osg::Vec2(windows[i][0], windows[i][1]) / 100.0); nrms->push_back(nrm); } gtess->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, nstart, 20)); nstart += 20; // demonstrate that the Tessellator makes textured tessellations osg::StateSet *stateset = new osg::StateSet(); osg::Image *image = osgDB::readImageFile("Cubemap_snow/posy.jpg"); if (image) { osg::Texture2D *texture = new osg::Texture2D; texture->setImage(image); texture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::REPEAT); texture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::REPEAT); stateset->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON); } gtess->setStateSet(stateset); // We use a Tessellator to produce the tessellation required once only // and the contours are discarded. osg::ref_ptr<osgUtil::Tessellator> tscx = new osgUtil::Tessellator; // the v1.2 multi-contour Tessellator. tscx->setTessellationType(osgUtil::Tessellator::TESS_TYPE_GEOMETRY); tscx->setBoundaryOnly(false); tscx->setWindingType(osgUtil::Tessellator::TESS_WINDING_ODD); // so that first change in wind type makes the commonest tessellation - ODD. tscx->retessellatePolygons(*gtess); return gtess; }
// Construct grid surface representation of data void Surface::constructGrid(PrimitiveList& primitiveList, const Axes& axes, const Array<double>& displayAbscissa, List<DisplayDataSet>& displayData, ColourScale colourScale) { // Forget all data in current primitives primitiveList.forgetAll(); // Get extents of displayData to use based on current axes limits Vec3<int> minIndex, maxIndex; if (!calculateExtents(axes, displayAbscissa, displayData, minIndex, maxIndex)) return; int nZ = (maxIndex.z - minIndex.z) + 1; // Copy and transform abscissa values (still in data space) into axes coordinates Array<double> x(displayAbscissa, minIndex.x, maxIndex.x); axes.transformX(x); int nX = x.nItems(); if (nX < 2) return; // Decide how large to make VertexChunks in Primitives // We will consider multiple slices at once in order to take most advantage of the post-transform cache // forming (abscissa.nItems()/(cacheSize-1)+1) Primitives (we divide by (cacheSize-1) because we will force an overlap // of one gridpoint between adjacent strips). const int cacheSize = 12; int nPrimitives = x.nItems()/(cacheSize-1) + 1; // Get some values from axes so we can calculate colours properly bool yLogarithmic = axes.logarithmic(1); double yStretch = axes.stretch(1); // Reinitialise primitive list primitiveList.reinitialise(nPrimitives, true, GL_LINES, true); // Temporary variables int n, offset = 0, i, nLimit, nMax; Vec4<GLfloat> colour; Vec3<double> nrm(0.0, 1.0, 0.0); Array<double> y; Array<DisplayDataSet::DataPointType> yType; DisplayDataSet** slices = displayData.array(); Primitive* currentPrimitive = primitiveList[0]; int verticesA[cacheSize], verticesB[cacheSize]; double z; // Loop over abscissa indices while (offset <= x.nItems()) { // Set nLimit to ensure we don't go beyond the end of the data arrays nLimit = std::min(cacheSize, x.nItems()-offset); // Loop over remaining displayData for (int slice = minIndex.z; slice <= maxIndex.z; ++slice) { // Grab arrays y.copy(slices[slice]->y(), minIndex.x+offset, minIndex.x+offset+nLimit-1); yType.copy(slices[slice]->yType(), minIndex.x+offset, minIndex.x+offset+nLimit-1); axes.transformY(y, yType); z = axes.transformZ(slices[slice]->z()); // Generate vertices for this row for (n=0; n<nLimit; ++n) { i = offset+n; if (yType.value(n) != DisplayDataSet::NoPoint) { // A value exists here, so define a vertex colourScale.colour(yLogarithmic ? pow(10.0, y.value(n) / yStretch) : y.value(n) / yStretch, colour); verticesB[n] = currentPrimitive->defineVertex(x.value(i), y.value(n), z, nrm, colour); // If the previous vertex on this row also exists, draw a line here if ((n != 0) && (verticesB[n-1] != -1)) currentPrimitive->defineIndices(verticesB[n-1], verticesB[n]); } else verticesB[n] = -1; } // Draw lines across slices (if slice != 0) if (slice != 0) { nMax = (maxIndex.z-slice) > 1 ? nLimit-1 : nLimit; for (n=0; n<nMax; ++n) { if ((verticesA[n] != -1) && (verticesB[n] != -1)) currentPrimitive->defineIndices(verticesA[n], verticesB[n]); } } // Store current vertices for next pass for (n=0; n<cacheSize; ++n) verticesA[n] = verticesB[n]; } // Move to next primitive and increase offset currentPrimitive = currentPrimitive->next; offset += cacheSize-1; } }
bool ConvexHull::InsertPoint(const float2 &point) { if (m_Count < 2) { CHNode *node = new CHNode; node->Point = point; if (m_Root == NULL) { m_Root = node; } else { node->Prev = m_Root; node->Next = m_Root; } m_Root->Next = node; m_Root->Prev = node; ++m_Count; return true; } CHNode *node = m_Root; const float2 &v0 = node->Prev->Point; const float2 &v1 = node->Point; float2 dir = v1 - v0; float2 nrm(-dir.y, dir.x); if (dot(point - v0, nrm) > 0) { do { node = node->Prev; const float2 &v0 = node->Prev->Point; const float2 &v1 = node->Point; float2 dir = v1 - v0; float2 nrm(-dir.y, dir.x); if (dot(point - v0, nrm) <= 0) { node = node->Next; break; } } while (true); } else { do { const float2 &v0 = node->Point; node = node->Next; const float2 &v1 = node->Point; float2 dir = v1 - v0; float2 nrm(-dir.y, dir.x); if (dot(point - v0, nrm) > 0) break; if (node == m_Root) return false; } while (true); } do { const float2 &v0 = node->Point; const float2 &v1 = node->Next->Point; float2 dir = v1 - v0; float2 nrm(-dir.y, dir.x); if (dot(point - v0, nrm) <= 0) { break; } // Delete this node node->Prev->Next = node->Next; node->Next->Prev = node->Prev; CHNode *del = node; node = node->Next; delete del; --m_Count; } while (true); CHNode *new_node = new CHNode; new_node->Point = point; ++m_Count; new_node->Prev = node->Prev; new_node->Next = node; node->Prev->Next = new_node; node->Prev = new_node; m_Root = new_node; return true; }
void normalise() { double norm = nrm(); double inv_norm = 1.0 / (norm + (norm == 0)); _imaginary *= inv_norm; _real *= inv_norm; }
cloud_normal_t::Ptr read_scan_with_normals(e57::Reader& reader, uint32_t scan_index, const Eigen::Vector3d& demean_offset) { e57::Data3D header; reader.ReadData3D(scan_index, header); int64_t nColumn = 0, nRow = 0, nPointsSize = 0, nGroupsSize = 0, nCounts = 0; bool bColumnIndex = 0; reader.GetData3DSizes(scan_index, nRow, nColumn, nPointsSize, nGroupsSize, nCounts, bColumnIndex); int64_t n_size = (nRow > 0) ? nRow : 1024; double* data_x = new double[n_size], * data_y = new double[n_size], * data_z = new double[n_size]; double* nrm_x = new double[n_size], * nrm_y = new double[n_size], * nrm_z = new double[n_size]; int8_t valid_normals = 0; auto block_read = reader.SetUpData3DPointsData( scan_index, n_size, data_x, data_y, data_z, NULL, NULL, NULL, NULL, NULL, NULL, NULL, nrm_x, nrm_y, nrm_z, &valid_normals); Eigen::Affine3d rotation; rotation = Eigen::Quaterniond(header.pose.rotation.w, header.pose.rotation.x, header.pose.rotation.y, header.pose.rotation.z); Eigen::Affine3d registration; registration = Eigen::Translation<double, 3>( header.pose.translation.x + demean_offset[0], header.pose.translation.y + demean_offset[1], header.pose.translation.z + demean_offset[2]) * rotation; Eigen::Affine3d normal_transformation; normal_transformation = rotation.matrix().inverse().transpose(); unsigned long size = 0; cloud_normal_t::Ptr scan(new cloud_normal_t()); while ((size = block_read.read()) > 0) { for (unsigned long i = 0; i < size; i++) { point_normal_t p; Eigen::Vector3d pos(data_x[i], data_y[i], data_z[i]); pos = registration * pos; p.x = static_cast<float>(pos[0]); p.y = static_cast<float>(pos[1]); p.z = static_cast<float>(pos[2]); Eigen::Vector3d nrm(nrm_x[i], nrm_y[i], nrm_z[i]); nrm = normal_transformation * nrm; p.normal[0] = static_cast<float>(nrm[0]); p.normal[1] = static_cast<float>(nrm[1]); p.normal[2] = static_cast<float>(nrm[2]); scan->push_back(p); } } block_read.close(); delete[] data_x; delete[] data_y; delete[] data_z; delete[] nrm_x; delete[] nrm_y; delete[] nrm_z; // get origin position scan->sensor_origin_ = Eigen::Vector4f(header.pose.translation.x + demean_offset[0], header.pose.translation.y + demean_offset[1], header.pose.translation.z + demean_offset[2], 1.0); return scan; }
void Sprite::Render(Video* video, DWORD flags) { if (shade < 0.001 || hidden || !visible || !video) return; if (blend_mode == 2 && !(flags & Graphic::RENDER_ALPHA)) return; if (blend_mode == 4 && !(flags & Graphic::RENDER_ADDITIVE)) return; if (life > 0 || loop) { const Camera* camera = video->GetCamera(); Matrix orient(camera->Orientation()); Vec3 nrm(camera->vpn() * -1); ColorValue white((float) shade, (float) shade, (float) shade, (float) shade); ColorValue whiten((float) shade/3, (float) shade/3, (float) shade/3, (float) shade/3); DWORD diff = white.ToColor().Value(); orient.Roll(angle); Vec3 vx = Vec3((float) orient(0,0), (float) orient(0,1), (float) orient(0,2)) * (float) (w/2.0f); Vec3 vy = Vec3((float) orient(1,0), (float) orient(1,1), (float) orient(1,2)) * (float) (h/2.0f); vset.loc[0] = loc - vx + vy; vset.nrm[0] = nrm; vset.diffuse[0] = diff; vset.loc[1] = loc + vx + vy; vset.nrm[1] = nrm; vset.diffuse[1] = diff; vset.loc[2] = loc + vx - vy; vset.nrm[2] = nrm; vset.diffuse[2] = diff; vset.loc[3] = loc - vx - vy; vset.nrm[3] = nrm; vset.diffuse[3] = diff; if (luminous) { mtl.Ka = Color::Black; mtl.Kd = Color::Black; mtl.Ks = Color::Black; mtl.Ke = white; mtl.tex_diffuse = Frame(); mtl.tex_emissive = Frame(); mtl.blend = blend_mode; mtl.luminous = luminous; } else { mtl.Ka = white; mtl.Kd = white; mtl.Ks = Color::Black; mtl.Ke = whiten; //Color::Black; mtl.tex_diffuse = Frame(); mtl.tex_emissive = Frame(); //0; mtl.blend = blend_mode; mtl.luminous = luminous; } video->DrawPolys(1, &poly); } memset(&screen_rect, 0, sizeof(Rect)); }
osg::Geometry* makePolsTwo(void) { // an example of using current geometry contours to create next tessellation // this polygon disappears once the contour rules make no polygons. tessellateDemoGeometry *gtess = new tessellateDemoGeometry; int i; osg::Vec3Array *coords = new osg::Vec3Array; osg::Vec3Array *nrms = new osg::Vec3Array; osg::Vec2Array *tcs = new osg::Vec2Array; osg::Vec3 nrm(0, -1, 0); static GLdouble quadstrip[8][3] = { { 1900.0, 1130.0, 0.0 }, { 2100.0, 1130.0, 0.0 }, { 1900.0, 1350.0, 0.0 }, { 1950.0, 1350.0, 0.0 }, { 1900.0, 1550.0, 0.0 }, { 2000.0, 1550.0, 0.0 }, { 1900.0, 1750.0, 0.0 }, { 2400.0, 1750.0, 0.0 } }; static GLdouble innerquadstrip[8][3] = { { 2000.0, 1230.0, 0.0 }, { 2050.0, 1230.0, 0.0 }, { 1920.0, 1350.0, 0.0 }, { 1940.0, 1350.0, 0.0 }, { 1920.0, 1550.0, 0.0 }, { 1980.0, 1550.0, 0.0 }, { 2000.0, 1650.0, 0.0 }, { 2400.0, 1650.0, 0.0 } }; // add one large quadstrip for (i = 0; i < 8; i++) { coords->push_back(osg::Vec3(quadstrip[i][0], quadstrip[i][2], quadstrip[i][1])); tcs->push_back(osg::Vec2(quadstrip[i][0], quadstrip[i][1]) / 200.0); nrms->push_back(nrm); } for (i = 0; i < 8; i++) { coords->push_back(osg::Vec3(innerquadstrip[i][0], innerquadstrip[i][2], innerquadstrip[i][1])); tcs->push_back(osg::Vec2(innerquadstrip[i][0], innerquadstrip[i][1]) / 200.0); nrms->push_back(nrm); } gtess->setVertexArray(coords); gtess->setNormalArray(nrms, osg::Array::BIND_PER_VERTEX); gtess->setTexCoordArray(0, tcs); // demonstrate that the Tessellator makes textured tessellations osg::StateSet *stateset = new osg::StateSet(); osg::Image *image = osgDB::readImageFile("Cubemap_snow/posy.jpg"); if (image) { osg::Texture2D *texture = new osg::Texture2D; texture->setImage(image); texture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::REPEAT); texture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::REPEAT); stateset->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON); } gtess->setStateSet(stateset); int nstart = 0; // The derived class tessellateDemoGeometry retains the original contours for re-use. gtess->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_STRIP, nstart, 8)); nstart += 8; gtess->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_STRIP, nstart, 8)); nstart += 8; gtess->setTessellationType(osgUtil::Tessellator::TESS_TYPE_GEOMETRY); gtess->setBoundaryOnly(true); gtess->setWindingType(osgUtil::Tessellator::TESS_WINDING_ABS_GEQ_TWO); // so that first change in wind type makes the commonest tessellation - ODD. return gtess; }
// Construct full surface representation of data void Surface::constructFull(PrimitiveList& primitiveList, const Axes& axes, const Array<double>& displayAbscissa, List<DisplayDataSet>& displayData, ColourScale colourScale) { // Forget all data in current primitives primitiveList.forgetAll(); // Get extents of displayData to use based on current axes limits Vec3<int> minIndex, maxIndex; if (!calculateExtents(axes, displayAbscissa, displayData, minIndex, maxIndex)) return; int nZ = (maxIndex.z - minIndex.z) + 1; // Copy and transform abscissa values (still in data space) into axes coordinates Array<double> x(displayAbscissa, minIndex.x, maxIndex.x); axes.transformX(x); int nX = x.nItems(); // Check for specific actions when we have a low number of display datasets if (nZ == 1) { // Special case, if there is exactly one dataset, draw a standard XY line surface instead constructLineXY(primitiveList, axes, displayAbscissa, displayData, colourScale); return; } if (nX == 1) { // Special case, if there is exactly one dataset, draw a standard XY line surface instead constructLineZY(primitiveList, axes, displayAbscissa, displayData, colourScale); return; } // Resize primitive list so it's large enough for our needs primitiveList.reinitialise(nZ-1, false, GL_TRIANGLES, true); // Temporary variables Array< Vec3<double> > normA, normB; Array<double> yA, yB, yC; Array<DisplayDataSet::DataPointType> typeA, typeB, typeC; Array< Vec4<GLfloat> > colourA, colourB; QColor colour; double zA, zB, zC; Vec3<double> nrm(0.0, 1.0, 0.0); // Construct first slice data and set initial min/max values yA.copy(displayData[minIndex.z]->y(), minIndex.x, maxIndex.x); typeA.copy(displayData[minIndex.z]->yType(), minIndex.x, maxIndex.x); axes.transformY(yA, typeA); zA = axes.transformZ(displayData[minIndex.z]->z()); if ((minIndex.z+1) <= maxIndex.z) // Safety check - this should always be true because of the checks above { yB.copy(displayData[minIndex.z+1]->y(), minIndex.x, maxIndex.x); typeB.copy(displayData[minIndex.z+1]->yType(), minIndex.x, maxIndex.x); axes.transformY(yB, typeB); zB = axes.transformZ(displayData[minIndex.z+1]->z()); } constructSurfaceStrip(x, yA, zA, axes, normA, colourA, colourScale, yC, 0.0, yB, zB); // Create triangles in strips between the previous and target Y/Z values int nBit, nPlusOneBit, totalBit; int vertexAn = -1, vertexBn = -1, vertexAnPlusOne = -1, vertexBnPlusOne = -1; Primitive* currentPrimitive = primitiveList[0]; for (int index = minIndex.z+1; index <=maxIndex.z; ++index) { // Grab next data (if we are not at the end of the index range) if (index < maxIndex.z) { yC.copy(displayData[index+1]->y(), minIndex.x, maxIndex.x); typeC.copy(displayData[index+1]->yType(), minIndex.x, maxIndex.x); axes.transformY(yC, typeC); zC = axes.transformZ(displayData[index+1]->z()); } else yC.clear(); // Construct data for current slice constructSurfaceStrip(x, yB, zB, axes, normB, colourB, colourScale, yA, zA, yC, zC); // Use a simple bit to quickly determine which triangles to draw, given possible lack of datapoints in slices // // n n+1 n n+1 // Slice A 4-------1 4-------1 0 = Both 5 = None // | ....TR| |TL.... | 1 = BL 6 = None // | ....| |.... | 2 = TL 7 = None // |BL ..| |.. BR| 3 = None 8 = TR // Slice B 8-------2 8-------2 4 = BR 9+= None // Set initial bit, and generate initial vertices nBit = 0; if (typeA.value(0) == DisplayDataSet::NoPoint) { nBit += 4; vertexAn = -1; } else vertexAn = currentPrimitive->defineVertex(x.value(0), yA.value(0), zA, normA[0], colourA[0]); if (typeB.value(0) == DisplayDataSet::NoPoint) { nBit += 8; vertexBn = -1; } else vertexBn = currentPrimitive->defineVertex(x.value(0), yB.value(0), zB, normB[0], colourB[0]); for (int n=0; n<nX-1; ++n) { // Construct bit for n+1 nPlusOneBit = 0; if (typeA.value(n+1) == DisplayDataSet::NoPoint) nPlusOneBit += 1; if (typeB.value(n+1) == DisplayDataSet::NoPoint) nPlusOneBit += 2; totalBit = nBit + nPlusOneBit; // Reset indices for current (n+1) column vertexAnPlusOne = -1; vertexBnPlusOne = -1; // Add triangles for this quadrant if (totalBit == 0) { // Draw both if (vertexAn == -1) vertexAn = currentPrimitive->defineVertex(x.value(n), yA.value(n), zA, normA[n], colourA[n]); if (vertexBn == -1) vertexBn = currentPrimitive->defineVertex(x.value(n), yB.value(n), zB, normB[n], colourB[n]); vertexAnPlusOne = currentPrimitive->defineVertex(x.value(n+1), yA.value(n+1), zA, normA[n+1], colourA[n+1]); vertexBnPlusOne = currentPrimitive->defineVertex(x.value(n+1), yB.value(n+1), zB, normB[n+1], colourB[n+1]); currentPrimitive->defineIndices(vertexAn, vertexAnPlusOne, vertexBnPlusOne); currentPrimitive->defineIndices(vertexAn, vertexBn, vertexBnPlusOne); } else if (totalBit == 1) { // Bottom left corner only if (vertexAn == -1) vertexAn = currentPrimitive->defineVertex(x.value(n), yA.value(n), zA, normA[n], colourA[n]); if (vertexBn == -1) vertexBn = currentPrimitive->defineVertex(x.value(n), yB.value(n), zB, normB[n], colourB[n]); vertexBnPlusOne = currentPrimitive->defineVertex(x.value(n+1), yB.value(n+1), zB, normB[n+1], colourB[n+1]); currentPrimitive->defineIndices(vertexAn, vertexBnPlusOne, vertexBn); } else if (totalBit == 2) { // Top left corner only if (vertexAn == -1) vertexAn = currentPrimitive->defineVertex(x.value(n), yA.value(n), zA, normA[n], colourA[n]); if (vertexBn == -1) vertexBn = currentPrimitive->defineVertex(x.value(n), yB.value(n), zB, normB[n], colourB[n]); vertexAnPlusOne = currentPrimitive->defineVertex(x.value(n+1), yA.value(n+1), zA, normA[n+1], colourA[n]); currentPrimitive->defineIndices(vertexAn, vertexAnPlusOne, vertexBn); } else if (totalBit == 4) { // Bottom right corner only if (vertexBn == -1) vertexBn = currentPrimitive->defineVertex(x.value(n), yB.value(n), zB, normB[n], colourB[n]); vertexAnPlusOne = currentPrimitive->defineVertex(x.value(n+1), yA.value(n+1), zA, normA[n+1], colourA[n+1]); vertexBnPlusOne = currentPrimitive->defineVertex(x.value(n+1), yB.value(n+1), zB, normB[n+1], colourB[n+1]); currentPrimitive->defineIndices(vertexAnPlusOne, vertexBnPlusOne, vertexBn); } else if (totalBit == 8) { // Top right corner only if (vertexAn == -1) vertexAn = currentPrimitive->defineVertex(x.value(n), yA.value(n), zA, normA[n], colourA[n]); vertexAnPlusOne = currentPrimitive->defineVertex(x.value(n+1), yA.value(n+1), zA, normA[n+1], colourA[n+1]); vertexBnPlusOne = currentPrimitive->defineVertex(x.value(n+1), yB.value(n+1), zB, normB[n+1], colourB[n+1]); currentPrimitive->defineIndices(vertexAn, vertexAnPlusOne, vertexBnPlusOne); } // Store new nBit for next index nBit = nPlusOneBit*4; vertexAn = vertexAnPlusOne; vertexBn = vertexBnPlusOne; } // Shuffle data backwards... yA = yB; zA = zB; typeA = typeB; normA = normB; colourA = colourB; yB = yC; zB = zC; typeB = typeC; // Increment primitive pointer currentPrimitive = currentPrimitive->next; } }
void HMMWV_ReissnerTire::CreateMesh(const ChFrameMoving<>& wheel_frame, VehicleSide side) { // Create piece-wise cubic spline approximation of the tire profile. // x - radial direction // y - transversal direction ChCubicSpline splineX(m_profile_t, m_profile_x); ChCubicSpline splineY(m_profile_t, m_profile_y); // Create the mesh nodes. // The nodes are first created in the wheel local frame, assuming Y as the tire axis, // and are then transformed to the global frame. for (int i = 0; i < m_div_circumference; i++) { double phi = (CH_C_2PI * i) / m_div_circumference; ChVector<> nrm(-std::sin(phi), 0, std::cos(phi)); for (int j = 0; j <= m_div_width; j++) { double t_prf = double(j) / m_div_width; double x_prf, xp_prf, xpp_prf; double y_prf, yp_prf, ypp_prf; splineX.Evaluate(t_prf, x_prf, xp_prf, xpp_prf); splineY.Evaluate(t_prf, y_prf, yp_prf, ypp_prf); // Node position with respect to rim center double x = (m_rim_radius + x_prf) * std::cos(phi); double y = y_prf; double z = (m_rim_radius + x_prf) * std::sin(phi); // Node position in global frame (actual coordinate values) ChVector<> loc = wheel_frame.TransformPointLocalToParent(ChVector<>(x, y, z)); // Node direction ChVector<> tan_prf(std::cos(phi) * xp_prf, yp_prf, std::sin(phi) * xp_prf); ChVector<> nrm_prf = Vcross(tan_prf, nrm).GetNormalized(); ChVector<> dir = wheel_frame.TransformDirectionLocalToParent(nrm_prf); ChMatrix33<> mrot; mrot.Set_A_Xdir(tan_prf,nrm_prf); auto node = std::make_shared<ChNodeFEAxyzrot>(ChFrame<>(loc, mrot)); // Node velocity ChVector<> vel = wheel_frame.PointSpeedLocalToParent(ChVector<>(x, y, z)); node->SetPos_dt(vel); node->SetMass(0); m_mesh->AddNode(node); } } // Create the Reissner shell elements for (int i = 0; i < m_div_circumference; i++) { for (int j = 0; j < m_div_width; j++) { // Adjacent nodes int inode0, inode1, inode2, inode3; inode1 = j + i * (m_div_width + 1); inode2 = j + 1 + i * (m_div_width + 1); if (i == m_div_circumference - 1) { inode0 = j; inode3 = j + 1; } else { inode0 = j + (i + 1) * (m_div_width + 1); inode3 = j + 1 + (i + 1) * (m_div_width + 1); } auto node0 = std::dynamic_pointer_cast<ChNodeFEAxyzrot>(m_mesh->GetNode(inode0)); auto node1 = std::dynamic_pointer_cast<ChNodeFEAxyzrot>(m_mesh->GetNode(inode1)); auto node2 = std::dynamic_pointer_cast<ChNodeFEAxyzrot>(m_mesh->GetNode(inode2)); auto node3 = std::dynamic_pointer_cast<ChNodeFEAxyzrot>(m_mesh->GetNode(inode3)); // Create the element and set its nodes. auto element = std::make_shared<ChElementShellReissner4>(); element->SetNodes(node0, node1, node2, node3); // Element dimensions double len_circumference = 0.5 * ((node1->GetPos() - node0->GetPos()).Length() + (node3->GetPos() - node2->GetPos()).Length()); double len_width = (node2->GetPos() - node0->GetPos()).Length(); // Figure out the section for this element int b1 = m_num_elements_bead; int b2 = m_div_width - m_num_elements_bead; int s1 = b1 + m_num_elements_sidewall; int s2 = b2 - m_num_elements_sidewall; if (j < b1 || j >= b2) { // Bead section for (unsigned int im = 0; im < m_num_layers_bead; im++) { element->AddLayer(m_layer_thickness_bead[im], CH_C_DEG_TO_RAD * m_ply_angle_bead[im], m_materials[m_material_id_bead[im]]); } } else if (j < s1 || j >= s2) { // Sidewall section for (unsigned int im = 0; im < m_num_layers_sidewall; im++) { element->AddLayer(m_layer_thickness_sidewall[im], CH_C_DEG_TO_RAD * m_ply_angle_sidewall[im], m_materials[m_material_id_sidewall[im]]); } } else { // Tread section for (unsigned int im = 0; im < m_num_layers_tread; im++) { element->AddLayer(m_layer_thickness_tread[im], CH_C_DEG_TO_RAD * m_ply_angle_tread[im], m_materials[m_material_id_tread[im]]); } } // Set other element properties element->SetAlphaDamp(m_alpha); // Add element to mesh m_mesh->AddElement(element); } } // Switch on automatic gravity m_mesh->SetAutomaticGravity(true); }
int analyse(const char* filename, const char* outFile){ Mat img = cv_imread(filename), imgG, imgTmp; if(!img.data){ //cerr << "invalid image" << endl; throw "[ghosts] invalid image"; } cvtColor(img, imgG, CV_BGR2GRAY); int bCntX = (img.cols - w ) / bSize, bCntY = (img.rows - w) / bSize; int bCnt = bCntX * bCntY; int bCntR = bCnt; int res = 0; vector<vector<vector<double> > > bGhosts(bCnt); vector<vector<vector<double> > > bInv(bCnt); vector<double> bPredict(bCnt); for(int i = 0; i < bCnt; i++){ bGhosts[i].resize(w * w); for(int j = 0; j < w * w; j++) bGhosts[i][j].resize(101); } double elaAv = 0.0; for(int q = min(qNorm, qMin); q <= qMax; q++){ if(!(q == qNorm || (q >= qMin && q <= qMax))) continue; for(int j = 0; j < w * w; j++){ Rect curRoi = Rect(j % w, j / w, img.cols - j % w, img.rows - j / w); vector<int> compParams; vector<uchar> buff; compParams.push_back(CV_IMWRITE_JPEG_QUALITY); compParams.push_back(q); imencode(".jpg", imgG(curRoi), buff, compParams); imgTmp = imdecode(buff, 0); for(int i = 0; i < bCnt; i++){ bGhosts[i][j][q] = calcDiff(imgG(curRoi), imgTmp, bCoordX, bCoordY, bCoordX + bSize, bCoordY + bSize); if(q == qNorm && j == 1) elaAv += bGhosts[i][j][q]; } } fprintf(stderr, "\r%d", q); } elaAv /= bCnt; for(int i = 0; i < bCnt; i++){ vector<double> predictArgsV; predictArgsV.push_back(bCoordX); predictArgsV.push_back(bCoordY); predictArgsV.push_back(elaAv); predictArgsV.push_back(bGhosts[i][1][qNorm]); bPredict[i] = predictF(imgG, predictArgsV); if(bPredict[i] == 1) bCntR--; } for(int i = 0; i < bCnt; i++) for(int j = 0; j < w * w; j++) bGhosts[i][j] = nrm(bGhosts[i][j]); if(1){ for(int i = 0; i < bCnt; i++){ bInv[i].resize(101); if(bPredict[i] == 1) continue; vector<double> m1V(101), m2V(101); for(int q = qMin; q <= qMax; q++){ for(int j = 1; j < w * w; j++) // -- j = 1 m1V[q] += bGhosts[i][j][q]; m1V[q] /= w * w - 1; } for(int q = qMin; q <= qMax; q++){ for(int j = 1; j < w * w; j++) // -- j = 1 m2V[q] += bGhosts[i][j][q] * bGhosts[i][j][q]; m2V[q] = sqrt(m2V[q] / (w * w - 1) - m1V[q] * m1V[q]); } for(int q = qMin; q <= qMax; q++){ double maxD = -1, minD = 2; for(int j = 1; j < w * w; j++){ // -- j = 1 if(bGhosts[i][j][q] < minD) minD = bGhosts[i][j][q]; if(bGhosts[i][j][q] > maxD) maxD = bGhosts[i][j][q]; } double dlt = max((maxD - minD) / 3.0, 0.01); double dlt1 = max((maxD - minD) / 6.0, 0.004); if((bGhosts[i][0][q] < minD - dlt || bGhosts[i][0][q] > maxD + dlt)/* && q <= qMax - 3 && q >= qMin + 3*/){ bInv[i][q].push_back(1); }else bInv[i][q].push_back(0); if((bGhosts[i][0][q] < minD - dlt1 || bGhosts[i][0][q] > maxD + dlt1)/* && q <= qMax - 3 && q >= qMin + 3*/){ bInv[i][q].push_back(1); }else bInv[i][q].push_back(0); } } vector<double> qMask(101); int qMaskCnt = 0; for(int q = qMin; q <= qMax; q++){ for(int i = 0; i < bCnt; i++){ if(bPredict[i] == 1) continue; if(bInv[i][q][0] == 1) qMask[q]++; } if(qMask[q] / bCntR > 0.5){ qMask[q] = 1; qMaskCnt++; }else qMask[q] = 0; cerr << qMask[q]; } cerr << endl; if(qMaskCnt < 3){ //cerr << "don't want to analyse" << endl; //throw "[ghosts] don't want to analyse"; return -1; } for(int i = 0; i < bCnt; i++){ int clr; if(bPredict[i] == 1) clr = 0; else{ int tmpI2 = 0; for(int q = qMin; q <= qMax; q++) if(qMask[q] == 1 && bInv[i][q][1] == 1){ tmpI2++; } if((tmpI2 <= 0 && qMaskCnt >= 3) || (tmpI2 <= 1 && qMaskCnt >= 4) || (tmpI2 <= 2 && qMaskCnt >= 5) || (tmpI2 <= 3 && qMaskCnt >= 8)) tmpI2 = 0; clr = (tmpI2 == 0); } if(clr){ res++; for(int ix = bCoordX; ix < bCoordX + bSize; ix++) for(int iy = bCoordY; iy < bCoordY + bSize; iy++) img.at<Vec3b>(iy, ix)[2] = 255; } } if(outFile) cv_imwrite(outFile, img); } return res; }