bool polygon_ctrl_impl::check_edge(unsigned i, double x, double y) const { bool ret = false; unsigned n1 = i; unsigned n2 = (i + m_num_points - 1) % m_num_points; double x1 = xn(n1); double y1 = yn(n1); double x2 = xn(n2); double y2 = yn(n2); double dx = x2 - x1; double dy = y2 - y1; if (sqrt(dx * dx + dy * dy) > 0.0000001) { double x3 = x; double y3 = y; double x4 = x3 - dy; double y4 = y3 + dx; double den = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1); double u1 = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / den; double xi = x1 + u1 * (x2 - x1); double yi = y1 + u1 * (y2 - y1); dx = xi - x; dy = yi - y; if (u1 > 0.0 && u1 < 1.0 && sqrt(dx * dx + dy * dy) <= m_point_radius) { ret = true; } } return ret; }
unsigned polygon_ctrl_impl::vertex(double* x, double* y) { unsigned cmd = path_cmd_stop; double r = m_point_radius; if(m_status == 0) { cmd = m_stroke.vertex(x, y); if(!is_stop(cmd)) { transform_xy(x, y); return cmd; } if(m_node >= 0 && m_node == int(m_status)) r *= 1.2; m_ellipse.init(xn(m_status), yn(m_status), r, r, 32); ++m_status; } cmd = m_ellipse.vertex(x, y); if(!is_stop(cmd)) { transform_xy(x, y); return cmd; } if(m_status >= m_num_points) return path_cmd_stop; if(m_node >= 0 && m_node == int(m_status)) r *= 1.2; m_ellipse.init(xn(m_status), yn(m_status), r, r, 32); ++m_status; cmd = m_ellipse.vertex(x, y); if(!is_stop(cmd)) { transform_xy(x, y); } return cmd; }
//======= Crossings Multiply algorithm of InsideTest ======================== // // By Eric Haines, 3D/Eye Inc, [email protected] // // This version is usually somewhat faster than the original published in // Graphics Gems IV; by turning the division for testing the X axis crossing // into a tricky multiplication test this part of the test became faster, // which had the additional effect of making the test for "both to left or // both to right" a bit slower for triangles than simply computing the // intersection each time. The main increase is in triangle testing speed, // which was about 15% faster; all other polygon complexities were pretty much // the same as before. On machines where division is very expensive (not the // case on the HP 9000 series on which I tested) this test should be much // faster overall than the old code. Your mileage may (in fact, will) vary, // depending on the machine and the test data, but in general I believe this // code is both shorter and faster. This test was inspired by unpublished // Graphics Gems submitted by Joseph Samosky and Mark Haigh-Hutchinson. // Related work by Samosky is in: // // Samosky, Joseph, "SectionView: A system for interactively specifying and // visualizing sections through three-dimensional medical image data", // M.S. Thesis, Department of Electrical Engineering and Computer Science, // Massachusetts Institute of Technology, 1993. // // Shoot a test ray along +X axis. The strategy is to compare vertex Y values // to the testing point's Y and quickly discard edges which are entirely to one // side of the test ray. Note that CONVEX and WINDING code can be added as // for the CrossingsTest() code; it is left out here for clarity. // // Input 2D polygon _pgon_ with _numverts_ number of vertices and test point // _point_, returns 1 if inside, 0 if outside. bool polygon_ctrl_impl::point_in_polygon(double tx, double ty) const { if(m_num_points < 3) return false; if(!m_in_polygon_check) return false; unsigned j; int yflag0, yflag1, inside_flag; double vtx0, vty0, vtx1, vty1; vtx0 = xn(m_num_points - 1); vty0 = yn(m_num_points - 1); // get test bit for above/below X axis yflag0 = (vty0 >= ty); vtx1 = xn(0); vty1 = yn(0); inside_flag = 0; for (j = 1; j <= m_num_points; ++j) { yflag1 = (vty1 >= ty); // Check if endpoints straddle (are on opposite sides) of X axis // (i.e. the Y's differ); if so, +X ray could intersect this edge. // The old test also checked whether the endpoints are both to the // right or to the left of the test point. However, given the faster // intersection point computation used below, this test was found to // be a break-even proposition for most polygons and a loser for // triangles (where 50% or more of the edges which survive this test // will cross quadrants and so have to have the X intersection computed // anyway). I credit Joseph Samosky with inspiring me to try dropping // the "both left or both right" part of my code. if (yflag0 != yflag1) { // Check intersection of pgon segment with +X ray. // Note if >= point's X; if so, the ray hits it. // The division operation is avoided for the ">=" test by checking // the sign of the first vertex wrto the test point; idea inspired // by Joseph Samosky's and Mark Haigh-Hutchinson's different // polygon inclusion tests. if ( ((vty1-ty) * (vtx0-vtx1) >= (vtx1-tx) * (vty0-vty1)) == yflag1 ) { inside_flag ^= 1; } } // Move to the next pair of vertices, retaining info as possible. yflag0 = yflag1; vtx0 = vtx1; vty0 = vty1; unsigned k = (j >= m_num_points) ? j - m_num_points : j; vtx1 = xn(k); vty1 = yn(k); } return inside_flag != 0; }
bool polygon_ctrl_impl::on_mouse_move(double x, double y, bool button_flag) { bool ret = false; double dx; double dy; inverse_transform_xy(&x, &y); if(m_node == int(m_num_points)) { dx = x - m_dx; dy = y - m_dy; unsigned i; for(i = 0; i < m_num_points; i++) { xn(i) += dx; yn(i) += dy; } m_dx = x; m_dy = y; ret = true; } else { if(m_edge >= 0) { unsigned n1 = m_edge; unsigned n2 = (n1 + m_num_points - 1) % m_num_points; dx = x - m_dx; dy = y - m_dy; xn(n1) += dx; yn(n1) += dy; xn(n2) += dx; yn(n2) += dy; m_dx = x; m_dy = y; ret = true; } else { if(m_node >= 0) { xn(m_node) = x - m_dx; yn(m_node) = y - m_dy; ret = true; } } } return ret; }
void dampnewton(const FuncType &F, const JacType &DF, Eigen::VectorXd &x, double rtol = 1e-4,double atol = 1e-6) { const int n = x.size(); const double lmin = 1E-3; // Minimal damping factor double lambda = 1.0; // Initial and actual damping factor Eigen::VectorXd s(n),st(n); // Newton corrections Eigen::VectorXd xn(n); // Tentative new iterate double sn,stn; // Norms of Newton corrections do { auto jacfac = DF(x).lu(); // LU-factorize Jacobian s = jacfac.solve(F(x)); // Newton correction sn = s.norm(); // Norm of Newton correction lambda *= 2.0; do { lambda /= 2; if (lambda < lmin) throw "No convergence: lambda -> 0"; xn = x-lambda*s; // {\bf Tentative next iterate} st = jacfac.solve(F(xn)); // Simplified Newton correction stn = st.norm(); } while (stn > (1-lambda/2)*sn); // {\bf Natural monotonicity test} x = xn; // Now: xn accepted as new iterate lambda = std::min(2.0*lambda,1.0); // Try to mitigate damping } // Termination based on simplified Newton correction while ((stn > rtol*x.norm()) && (stn > atol)); }
// ukazkovy test int main(void) { int i; for (i = 0; i < 32; i++) printf("2^%d = %lf\n", i, xn(2.0, i)); return 0; }
osgToy::OctoStrip::OctoStrip() { osg::Vec3Array* vAry = dynamic_cast<osg::Vec3Array*>( getVertexArray() ); osg::Vec3Array* nAry = dynamic_cast<osg::Vec3Array*>( getNormalArray() ); setNormalBinding( osg::Geometry::BIND_PER_VERTEX ); osg::Vec4Array* cAry = dynamic_cast<osg::Vec4Array*>( getColorArray() ); setColorBinding( osg::Geometry::BIND_PER_VERTEX ); osg::Vec3 xp( 1, 0, 0); osg::Vec4 red(1,0,0,1); osg::Vec3 xn(-1, 0, 0); osg::Vec4 cyan(0,1,1,1); osg::Vec3 yp( 0, 1, 0); osg::Vec4 green(0,1,0,1); osg::Vec3 yn( 0,-1, 0); osg::Vec4 magenta(1,0,1,1); osg::Vec3 zp( 0, 0, 1); osg::Vec4 blue(0,0,1,1); osg::Vec3 zn( 0, 0,-1); osg::Vec4 yellow(1,1,0,1); vAry->push_back(zp); nAry->push_back(zp); cAry->push_back(blue); vAry->push_back(yp); nAry->push_back(yp); cAry->push_back(green); vAry->push_back(xn); nAry->push_back(xn); cAry->push_back(cyan); vAry->push_back(zn); nAry->push_back(zn); cAry->push_back(yellow); vAry->push_back(yn); nAry->push_back(yn); cAry->push_back(magenta); vAry->push_back(xp); nAry->push_back(xp); cAry->push_back(red); vAry->push_back(zp); nAry->push_back(zp); cAry->push_back(blue); vAry->push_back(yp); nAry->push_back(yp); cAry->push_back(green); addPrimitiveSet( new osg::DrawArrays( GL_TRIANGLE_STRIP, 0, vAry->size() ) ); }
bool interactive_polygon::on_mouse_move(double x, double y) { bool ret = false; double dx; double dy; if(m_node == int(m_num_points)) { dx = x - m_dx; dy = y - m_dy; unsigned i; for(i = 0; i < m_num_points; i++) { xn(i) += dx; yn(i) += dy; } m_dx = x; m_dy = y; ret = true; } else { if(m_edge >= 0) { unsigned n1 = m_edge; unsigned n2 = (n1 + m_num_points - 1) % m_num_points; dx = x - m_dx; dy = y - m_dy; xn(n1) += dx; yn(n1) += dy; xn(n2) += dx; yn(n2) += dy; m_dx = x; m_dy = y; ret = true; } else { if(m_node >= 0) { xn(m_node) = x - m_dx; yn(m_node) = y - m_dy; ret = true; } } } return ret; }
bool polygon_ctrl_impl::on_mouse_button_down(double x, double y) { unsigned i; bool ret = false; m_node = -1; m_edge = -1; inverse_transform_xy(&x, &y); for (i = 0; i < m_num_points; i++) { if(sqrt( (x-xn(i)) * (x-xn(i)) + (y-yn(i)) * (y-yn(i)) ) < m_point_radius) { m_dx = x - xn(i); m_dy = y - yn(i); m_node = int(i); ret = true; break; } } if(!ret) { for (i = 0; i < m_num_points; i++) { if(check_edge(i, x, y)) { m_dx = x; m_dy = y; m_edge = int(i); ret = true; break; } } } if(!ret) { if(point_in_polygon(x, y)) { m_dx = x; m_dy = y; m_node = int(m_num_points); ret = true; } } return ret; }
unsigned interactive_polygon::vertex(double* x, double* y) { unsigned cmd = path_cmd_stop; double r = m_point_radius; if(m_status == 0) { cmd = m_stroke.vertex(x, y); if(!is_stop(cmd)) return cmd; if(m_node >= 0 && m_node == int(m_status)) r *= 1.2; m_ellipse.init(xn(m_status), yn(m_status), r, r, 32); ++m_status; } cmd = m_ellipse.vertex(x, y); if(!is_stop(cmd)) return cmd; if(m_status >= m_num_points) return path_cmd_stop; if(m_node >= 0 && m_node == int(m_status)) r *= 1.2; m_ellipse.init(xn(m_status), yn(m_status), r, r, 32); ++m_status; return m_ellipse.vertex(x, y); }
void rlMain::addToStateVector(int& destino,int origem, int mudanca) { State x(StateVector[origem].currentState, mudanca); int temp = returnIndexOfMatch(x); if (temp == -1){ temp = ++destino; StateNode xn(x); StateVector[temp] = xn; } StateVector[origem].children[mudanca] = temp; }
bool polygon_ctrl_impl::check_edge(unsigned i, real x, real y) const { bool ret = false; unsigned n1 = i; unsigned n2 = (i + m_num_points - 1) % m_num_points; real x1 = xn(n1); real y1 = yn(n1); real x2 = xn(n2); real y2 = yn(n2); real dx = x2 - x1; real dy = y2 - y1; if(SQRT(dx*dx + dy*dy) > 0.0000001) { real x3 = x; real y3 = y; real x4 = x3 - dy; real y4 = y3 + dx; real den = (y4-y3) * (x2-x1) - (x4-x3) * (y2-y1); real u1 = ((x4-x3) * (y1-y3) - (y4-y3) * (x1-x3)) / den; real xi = x1 + u1 * (x2 - x1); real yi = y1 + u1 * (y2 - y1); dx = xi - x; dy = yi - y; if (u1 > 0.0f && u1 < 1.0f && SQRT(dx*dx + dy*dy) <= m_point_radius) { ret = true; } } return ret; }
// implementation: approximate gradient (if no analytic gradient provided) void eval_grad(const tvector& x, tvector& g) const { // accuracy epsilon as defined in: // see "Numerical optimization", Nocedal & Wright, 2nd edition, p.197 const tscalar dx = std::cbrt(tscalar(10) * std::numeric_limits<tscalar>::epsilon()); const tsize n = size(); tvector xp = x, xn = x; g.resize(n); for (tsize i = 0; i < n; i ++) { if (i > 0) { xp(i - 1) -= dx; xn(i - 1) += dx; } xp(i) += dx; xn(i) -= dx; g(i) = (m_op_fval(xp) - m_op_fval(xn)) / (xp(i) - xn(i)); } }
osgToy::RhombicDodecahedron::RhombicDodecahedron() { setOverallColor( osg::Vec4(0,1,0,1) ); osg::Vec3 a0( 1, 1, 1 ); osg::Vec3 a1( 1, 1, -1 ); osg::Vec3 a2( 1, -1, 1 ); osg::Vec3 a3( 1, -1, -1 ); osg::Vec3 a4( -1, 1, 1 ); osg::Vec3 a5( -1, 1, -1 ); osg::Vec3 a6( -1, -1, 1 ); osg::Vec3 a7( -1, -1, -1 ); osg::Vec3 xp( 2, 0, 0 ); osg::Vec3 xn( -2, 0, 0 ); osg::Vec3 yp( 0, 2, 0 ); osg::Vec3 yn( 0, -2, 0 ); osg::Vec3 zp( 0, 0, 2 ); osg::Vec3 zn( 0, 0, -2 ); addTristrip( yp, a0, a1, xp ); addTristrip( xp, a2, a3, yn ); addTristrip( yn, a6, a7, xn ); addTristrip( xn, a4, a5, yp ); addTristrip( zp, a0, a4, yp ); addTristrip( yp, a1, a5, zn ); addTristrip( zn, a3, a7, yn ); addTristrip( yn, a2, a6, zp ); addTristrip( xp, a0, a2, zp ); addTristrip( zp, a4, a6, xn ); addTristrip( xn, a5, a7, zn ); addTristrip( zn, a1, a3, xp ); osgToy::FacetingVisitor::facet( *this ); }
void Strand2dFCBlockSolver::rhsSource(const int& j) { // gradients of qa in n-direction and s-direction int j1,nj,nm; double dnr=1./deltaN; Array2D<double> qan(nSurfNode,nqa); Array3D<double> qas(nSurfElem,meshOrder+1,nqa); Array3D<double> ss(nSurfElem,meshOrder+1,nq); qan.set(0.); for (int n=0; n<nSurfNode; n++){ j1 = icn2[j][0]; nj = icn2[j][1]; for (int m=0; m<nj; m++){ for (int k=0; k<nqa; k++) qan(n,k) += dnr*icn1[j][m]*qa(n,j1,k); j1++; }} qas.set(0.); for (int n=0; n<nSurfElem; n++) for (int i=0; i<meshOrder+1; i++) // ith point in the element for (int m=0; m<meshOrder+1; m++){ // mth Lagrange poly. in mapping nm = surfElem(n,m); for (int k=0; k<nqa; k++) qas(n,i,k) += ls(i,m)*qa(nm,j,k); } // source computation int ni; double jac1,xs1,ys1,xn1,yn1,qax[nqa],qay[nqa],f[nq]; for (int n=0; n<nSurfElem; n++) for (int i=0; i<meshOrder+1; i++){ ni = surfElem(n,i); jac1 = 1./jac(n,i,j); xs1 = xs(n,i,j)*jac1; ys1 = ys(n,i,j)*jac1; xn1 = xn(ni,j)*jac1; yn1 = yn(ni,j)*jac1; for (int k=0; k<nqa; k++){ qax[k] = yn1*qas(n,i,k)-ys1*qan(ni,k); qay[k] =-xn1*qas(n,i,k)+xs1*qan(ni,k); } sys->rhsSource(1,&q(ni,j,0),&qa(ni,j,0),&qax[0],&qay[0],&f[0]); for (int k=0; k<nq; k++) ss(n,i,k) =-f[k]/jac1; } // source treatment int ne; double ns; for (int n=0; n<nSurfNode; n++) for (int i=psp2S(n); i<psp2S(n+1); i++){ ne = psp1S(i,0); ni = psp1S(i,1); ns = wsp1S(i); for (int k=0; k<nq; k++) r(n,j,k) += ns*ss(ne,ni,k); } // clean up qan.deallocate(); qas.deallocate(); ss.deallocate(); }
//"рисует" одну линию поля из начальной точки PointB //с помощью функций работающих с Z-буфером void LineField(HDC hdc,POINT3 PointB,COLORREF rgb, double force) { VECTORS vect; vect.x = PointB.x; vect.y = PointB.y; vect.z = PointB.z; //видовые координаты проецируемой точки double xe, ye, ze1, ze2; //координаты пикселов int x1,y1,x2,y2; double dt = force > 0 ? 0.1 : -0.1; //длина шага на линии поля double x, y, z, Hx, Hy, Hz, Ha; int k = 0; VECMAG mag; int step = 0; double xt1,yt1,zt1,xt2,yt2,zt2; do { step++; x = vect.x; y = vect.y; z = vect.z; mag = magn(x,y,z); Hx = mag.hx; Hy = mag.hy; Hz = mag.hz; Ha = sqrt(Hx*Hx + Hy*Hy + Hz*Hz); vect.dx = Hx/Ha; vect.dy = Hy/Ha; vect.dz = Hz/Ha; xt1 = vect.x; yt1 = vect.y; zt1 = vect.z; xt2 = xt1 + vect.dx*dt; yt2 = yt1 + vect.dy*dt; zt2 = zt1 + vect.dz*dt; xe = Xe(xt1, yt1, zt1); ye=Ye(xt1,yt1,zt1); ze1=Ze(xt1,yt1,zt1); x1=xn(xe); y1=ym(ye); xe = Xe(xt2, yt2, zt1); ye=Ye(xt2,yt2,zt2); ze2=Ze(xt2,yt2,zt2); x2=xn(xe); y2=ym(ye); //"рисуем" отрезок линии поля ZbufLineWidth(hdc,x1,y1,x2,y2,ze1,ze2,3,rgb); vect.x = xt2; vect.y = yt2; vect.z = zt2; //после 10-и шагов на лини поля "рисуем" стрелку k++; if(k == 10) { arrowVector(hdc,x1,y1,x2,y2,ze2,RGB(0,0,255)); k = 0; } //прекращаем рисовать линию поля на границе куба } while (step < 1000 && (x>-xmax) && (x<xmax) && (y>-ymax) && (y<ymax) && (z>-zmax) && (z<zmax)); }
//рисуем картину приложения void LinePicture(HWND hwnd, int Context) { //выбираем нужный контектс устройства для экрана //--------------------------------------------- HDC hdcWin; PAINTSTRUCT ps; //получаем контест устройства для экрана if(Context == 1) hdcWin = BeginPaint(hwnd, &ps); else hdcWin = GetDC(hwnd); //----------------------------------------------- //связываем размеры поля вывода с размерами клиентской области окна //-------------------------------------------------------------------- RECT rct; GetClientRect(hwnd,&rct); ne1 = rct.left+50; ne2 = rct.right -50; me1 = rct.bottom -50; me2 = rct.top + 50; //------------------------------------------------------------------ //создаем контекст экрана //------------------------------------------------------------ HDC hdc = CreateCompatibleDC(hdcWin); //создаем контекст //памяти связаный с контекстом экрана //памяти надо придать вид экрана - подходт битовая карта с форматом // как у экрана. В памяти будем рисовать на битовой карте HBITMAP hBitmap, hBitmapOld; hBitmap = CreateCompatibleBitmap(hdcWin, ne2, me1); //создаем //битовую карту совместмую с контекстом экрана hBitmapOld = (HBITMAP)SelectObject(hdc, hBitmap); //помещаем // битовую карту в контекст памяти //-------------------------------------------------------------- //выводи значения углов в верхней части поля вывода //-------------------------------------------------------- //создание прямоугольной области для вывода углов поворота HRGN hrgn2 = CreateRectRgn(ne1,me2-30,ne2,me1); //заливаем выделенную область серым цветом HBRUSH hBrush2 = CreateSolidBrush(RGB(0x80,0x80,0x80)); HBRUSH hBrushOld = (HBRUSH)SelectObject(hdc,hBrush2); FillRgn(hdc,hrgn2,hBrush2); SelectObject(hdc,hBrushOld); DeleteObject(hBrush2); DeleteObject(hrgn2); //вычисление угловых коэффициентов поворота системы координат sf=sin(M_PI*angl.fi/180); cf=cos(M_PI*angl.fi/180); st=sin(M_PI*angl.teta/180); ct=cos(M_PI*angl.teta/180); //информация об углах поворота системы координат TCHAR ss[20]; SetBkColor(hdc,RGB(0xC0,0xC0,0xC0)); SetTextColor(hdc,RGB(0,0,0x80)); swprintf_s(ss,20,L"fi = %4.0lf",angl.fi); TextOut(hdc,(ne1+ne2)/2-80,me2-25,ss,9); swprintf_s(ss,20,L"teta = %4.0lf",angl.teta); TextOut(hdc,(ne1+ne2)/2+20,me2-25,ss,11); //------------------------------------------------ //выделение памяти под Z-буфер и начальное его заполнение //------------------------------------------------------------- //вычисляем число пикселей в поле вывода Np = ne2-ne1 + 1, Mp = me1-me2 +1, NM = Np*Mp; //выделяем память под Z-буфер для каждого пикселя zb = new ZbuffS [NM]; //начальное заполнение z-буфера для каждого пикселя for ( long unsigned p=0; p<NM; p++) { zb[p].z = -1000; zb[p].c.R = 0xC0; zb[p].c.G = 0xC0; zb[p].c.B = 0xC0; } //----------------------------------------------------------- //"рисуем" магнитную пластинку заданным цветом заполняя Z-буфер //----------------------------------------------------------------------- //мировые координаты проецируемой точки double xt1,yt1,zt1; //видовые координаты проецируемой точки double xe,ye,ze1; //пиксельные координаты проецируемой точки int x1,y1; //пиксельные координаты 4-х углов пластинки int xp[4], yp[4]; //видовые z-координаты 4-х углов пластинки double ze[4]; for(int n=0; n<4; n++) { xt1 = Px[n]; yt1 = Py[n]; zt1 = Pz[n]; xe = Xe(xt1, yt1, zt1); ye=Ye(xt1,yt1,zt1); ze1=Ze(xt1,yt1,zt1); x1=xn(xe); y1=ym(ye); xp[n] = x1; yp[n] = y1; ze[n] = ze1; } //ZbufParallelogram(hdc,xp[0],yp[0],ze[0],xp[1],yp[1],ze[1], //xp[2],yp[2],ze[2],xp[3],yp[3],ze[3],RGB(255,255,0)); //------------------------------------------------------------------ //"рисуем" линии поля заполняя Z-буфер //---------------------------------------------------------------- for (int i = 0; i < 20; i++) { LineField(hdc,PointB[i],RGB(255,0,0),1); } for(int i=20; i<40; i++) { LineField(hdc,PointB[i],RGB(0,0,255), 1); } for (int i = 40; i<60; i++) { LineField(hdc, PointB[i], RGB(0, 255,0), 1); } //----------------------------------------------------------------------- //выводим содержимое Z-буфера в контекст памяти //-------------------------------------------------------------------- //двигаемся по всем пикселям окна вывода for (unsigned long ij=0; ij<NM; ij++) { x1 = ne1 + ij%Np; y1 = me2 + ij/Np; SetPixel(hdc,x1,y1,RGB(zb[ij].c.R,zb[ij].c.G,zb[ij].c.B)); } delete [] zb; //очищаем память под Z-буфером //------------------------------------------------------------- //рисуем координтные оси //------------------------------------------------------------------------ HPEN hPen = CreatePen(PS_SOLID,1,RGB(0,255,255)); HPEN hPenOld = (HPEN)SelectObject(hdc,hPen); int x2,y2; //ось Ox xe=Xe(-xmax/3,0,0); ye=Ye(-xmax/3,0,0); x1=xn(xe); y1=ym(ye); xe=Xe(xmax,0,0); ye=Ye(xmax,0,0); x2=xn(xe); y2=ym(ye); MoveToEx(hdc,x1,y1,NULL); LineTo(hdc,x2,y2); SetBkColor(hdc,RGB(0xC0,0xC0,0xC0)); SetTextColor(hdc,RGB(120,120,120)); TextOut(hdc,x2, y2, _T("X"),1); //Ось Oy xe=Xe(0,-ymax/3, 0); ye=Ye(0,-ymax/3,0); x1=xn(xe); y1=ym(ye); xe=Xe(0,ymax, 0); ye=Ye(0,ymax,0); x2=xn(xe); y2=ym(ye); MoveToEx(hdc,x1,y1,NULL); LineTo(hdc,x2,y2); SetBkColor(hdc,RGB(0xC0,0xC0,0xC0)); SetTextColor(hdc,RGB(120,120,120)); TextOut(hdc,x2, y2, _T("Y"),1); //Ось Oz xe=Xe(0,0, 0); ye=Ye(0,0,-zmax/3); x1=xn(xe); y1=ym(ye); xe=Xe(0,0, 0); ye=Ye(0,0,zmax); x2=xn(xe); y2=ym(ye); MoveToEx(hdc,x1,y1,NULL); LineTo(hdc,x2,y2); SetBkColor(hdc,RGB(0xC0,0xC0,0xC0)); SetTextColor(hdc,RGB(120,120,120)); TextOut(hdc,x2, y2, _T("Z"),1); SelectObject(hdc,hPenOld); DeleteObject(hPen); //----------------------------------------------------------------------------- //рисуем куб //---------------------------------------------------------------------- hPen = CreatePen(PS_SOLID,1,RGB(160,160,160)); hPenOld = (HPEN)SelectObject(hdc,hPen); DrawBox(hwnd, hdc, angl); SelectObject(hdc,hPenOld); DeleteObject(hPen); //------------------------------------------------------------------------ //копируем контекст памяти в контекст экрана //----------------------------------------------------------------------- BitBlt(hdcWin,ne1,me2-30,ne2,me1,hdc,ne1,me2-30,SRCCOPY); //---------------------------------------------------------------------- //завершаем работу с контекстами и памятью //------------------------------------------------------------------- SelectObject(hdc, hBitmapOld); //востанавливаем контекст памяти DeleteObject(hBitmap); //убираем битовую карту DeleteDC(hdc); // освобождаем контекст памяти //освобождаем контекст экрана if(Context == 1) EndPaint(hwnd, &ps); else ReleaseDC(hwnd, hdcWin); }
int Sphere::Triangulate(float3 *outPos, float3 *outNormal, float2 *outUV, int numVertices, bool ccwIsFrontFacing) const { assume(outPos); assume(numVertices >= 24 && "At minimum, sphere triangulation will contain at least 8 triangles, which is 24 vertices, but fewer were specified!"); assume(numVertices % 3 == 0 && "Warning:: The size of output should be divisible by 3 (each triangle takes up 3 vertices!)"); #ifndef MATH_ENABLE_INSECURE_OPTIMIZATIONS if (!outPos) return 0; #endif assume(this->r > 0.f); if (numVertices < 24) return 0; #ifdef MATH_ENABLE_STL_SUPPORT std::vector<Triangle> temp; #else Array<Triangle> temp; #endif // Start subdividing from a diamond shape. float3 xp(r,0,0); float3 xn(-r,0,0); float3 yp(0,r,0); float3 yn(0,-r,0); float3 zp(0,0,r); float3 zn(0,0,-r); if (ccwIsFrontFacing) { temp.push_back(Triangle(yp,xp,zp)); temp.push_back(Triangle(xp,yp,zn)); temp.push_back(Triangle(yn,zp,xp)); temp.push_back(Triangle(yn,xp,zn)); temp.push_back(Triangle(zp,xn,yp)); temp.push_back(Triangle(yp,xn,zn)); temp.push_back(Triangle(yn,xn,zp)); temp.push_back(Triangle(xn,yn,zn)); } else { temp.push_back(Triangle(yp,zp,xp)); temp.push_back(Triangle(xp,zn,yp)); temp.push_back(Triangle(yn,xp,zp)); temp.push_back(Triangle(yn,zn,xp)); temp.push_back(Triangle(zp,yp,xn)); temp.push_back(Triangle(yp,zn,xn)); temp.push_back(Triangle(yn,zp,xn)); temp.push_back(Triangle(xn,zn,yn)); } int oldEnd = 0; while(((int)temp.size()-oldEnd+3)*3 <= numVertices) { Triangle cur = temp[oldEnd]; float3 a = ((cur.a + cur.b) * 0.5f).ScaledToLength(this->r); float3 b = ((cur.a + cur.c) * 0.5f).ScaledToLength(this->r); float3 c = ((cur.b + cur.c) * 0.5f).ScaledToLength(this->r); temp.push_back(Triangle(cur.a, a, b)); temp.push_back(Triangle(cur.b, c, a)); temp.push_back(Triangle(cur.c, b, c)); temp.push_back(Triangle(a, c, b)); ++oldEnd; } // Check that we really did tessellate as many new triangles as possible. assert(((int)temp.size()-oldEnd)*3 <= numVertices && ((int)temp.size()-oldEnd)*3 + 9 > numVertices); for(size_t i = oldEnd, j = 0; i < temp.size(); ++i, ++j) { outPos[3*j] = this->pos + temp[i].a; outPos[3*j+1] = this->pos + temp[i].b; outPos[3*j+2] = this->pos + temp[i].c; } if (outNormal) for(size_t i = oldEnd, j = 0; i < temp.size(); ++i, ++j) { outNormal[3*j] = temp[i].a.Normalized(); outNormal[3*j+1] = temp[i].b.Normalized(); outNormal[3*j+2] = temp[i].c.Normalized(); } if (outUV) for(size_t i = oldEnd, j = 0; i < temp.size(); ++i, ++j) { outUV[3*j] = float2(atan2(temp[i].a.y, temp[i].a.x) / (2.f * 3.141592654f) + 0.5f, (temp[i].a.z + r) / (2.f * r)); outUV[3*j+1] = float2(atan2(temp[i].b.y, temp[i].b.x) / (2.f * 3.141592654f) + 0.5f, (temp[i].b.z + r) / (2.f * r)); outUV[3*j+2] = float2(atan2(temp[i].c.y, temp[i].c.x) / (2.f * 3.141592654f) + 0.5f, (temp[i].c.z + r) / (2.f * r)); } return ((int)temp.size() - oldEnd) * 3; }
//рисуем куб, связанный с подвижной системой координат void DrawBox(HWND hwnd, HDC hdc, ANGLS an) { sf=sin(M_PI*an.fi/180); cf=cos(M_PI*an.fi/180); st=sin(M_PI*an.teta/180); ct=cos(M_PI*an.teta/180); double xe, ye; int x1,y1,x2,y2; double xt1,yt1,zt1,xt2,yt2,zt2; int j; for(int i=0; i<4; i++) { j = i + 1; if(j==4) j = 0; xt1 = Point[i].x; yt1 = Point[i].y; zt1 = Point[i].z; xt2 = Point[j].x; yt2 = Point[j].y; zt2 = Point[j].z; xe = Xe(xt1, yt1, zt1); ye=Ye(xt1,yt1,zt1); x1=xn(xe); y1=ym(ye); xe = Xe(xt2, yt2, zt2); ye=Ye(xt2,yt2,zt2); x2=xn(xe); y2=ym(ye); MoveToEx(hdc,x1,y1,NULL); LineTo(hdc,x2,y2); } for(int i=4; i<8; i++) { j = i + 1; if(j==8) j = 4; xt1 = Point[i].x; yt1 = Point[i].y; zt1 = Point[i].z; xt2 = Point[j].x; yt2 = Point[j].y; zt2 = Point[j].z; xe = Xe(xt1, yt1, zt1); ye=Ye(xt1,yt1,zt1); x1=xn(xe); y1=ym(ye); xe = Xe(xt2, yt2, zt2); ye=Ye(xt2,yt2,zt2); x2=xn(xe); y2=ym(ye); MoveToEx(hdc,x1,y1,NULL); LineTo(hdc,x2,y2); } for(int i=0; i<4; i++) { xt1 = Point[i].x; yt1 = Point[i].y; zt1 = Point[i].z; xt2 = Point[i+4].x; yt2 = Point[i+4].y; zt2 = Point[i+4].z; xe = Xe(xt1, yt1, zt1); ye=Ye(xt1,yt1,zt1); x1=xn(xe); y1=ym(ye); xe = Xe(xt2, yt2, zt2); ye=Ye(xt2,yt2,zt2); x2=xn(xe); y2=ym(ye); MoveToEx(hdc,x1,y1,NULL); LineTo(hdc,x2,y2); } for(int i=0; i<2; i++) { xt1 = Point[i].x; yt1 = Point[i].y; zt1 = Point[i].z; xt2 = Point[i+2].x; yt2 = Point[i+2].y; zt2 = Point[i+2].z; xe = Xe(xt1, yt1, zt1); ye=Ye(xt1,yt1,zt1); x1=xn(xe); y1=ym(ye); xe = Xe(xt2, yt2, zt2); ye=Ye(xt2,yt2,zt2); x2=xn(xe); y2=ym(ye); MoveToEx(hdc,x1,y1,NULL); LineTo(hdc,x2,y2); } }
vector<double> CNelderMead::NelderMeadFunction(double (*f)(vector<double>, RMSEinputs rmsein), NMsettings nmset, vector<vector<double> > x) { int NumIters = 0; int i,j; double MaxIters = nmset.MaxIters; double tolerance = nmset.tolerance; int N = nmset.N; RMSEinputs rmsein = nmset.RMSEinp; double S = rmsein.S; double T = rmsein.T; double r = rmsein.r; // Value of the function at the vertices vector<vector<double> > F(N+1, vector<double>(2)); // Step 0. Ordering and Best and Worst points // Order according to the functional values, compute the best and worst points step0: NumIters += 1; for (j=0; j<=N; j++){ vector<double> z(N, 0.0); // Create vector to contain for (i=0; i<=N-1; i++) z[i] = x[i][j]; F[j][0] = f(z,rmsein); // Function values F[j][1] = j; // Original index positions } sort(F.begin(), F.end()); // New vertices order first N best initial vectors and // last (N+1)st vertice is the worst vector // y is the matrix of vertices, ordered so that the worst vertice is last vector<vector<double> > y(N, vector<double>(N+1)); for (j=0; j<=N; j++) for (i=0; i<=N-1; i++) y[i][j] = x[i][F[j][1]]; // First best vector y(1) and function value f1 vector<double> x1(N, 0.0); for (i=0; i<=N-1; i++) x1[i] = y[i][0]; double f1 = f(x1,rmsein); // Last best vector y(N) and function value fn vector<double> xn(N, 0.0); for (i=0; i<=N-1; i++) xn[i] = y[i][N-1]; double fn = f(xn,rmsein); // Worst vector y(N+1) and function value fn1 vector<double> xn1(N, 0.0); for (i=0; i<=N-1; i++) xn1[i] = y[i][N]; double fn1 = f(xn1,rmsein); // z is the first N vectors from y, excludes the worst y(N+1) vector<vector<double> > z(N, vector<double>(N)); for (j=0; j<=N-1; j++) for (i=0; i<=N-1; i++) z[i][j] = y[i][j]; // Mean of best N values and function value fm vector<double> xm(N, 0.0); xm = CNelderMead::VMean(z,N); double fm = f(xm,rmsein); // Reflection point xr and function fr vector<double> xr(N, 0.0); xr = CNelderMead::VSub(VAdd(xm, xm), xn1); double fr = f(xr,rmsein); // Expansion point xe and function fe vector<double> xe(N, 0.0); xe = CNelderMead::VSub(VAdd(xr, xr), xm); double fe = f(xe,rmsein); // Outside contraction point and function foc vector<double> xoc(N, 0.0); xoc = CNelderMead::VAdd(CNelderMead::VMult(xr, 0.5), VMult(xm, 0.5)); double foc = f(xoc,rmsein); // Inside contraction point and function foc vector<double> xic(N, 0.0); xic = CNelderMead::VAdd(CNelderMead::VMult(xm, 0.5), CNelderMead::VMult(xn1, 0.5)); double fic = f(xic,rmsein); while ((NumIters <= MaxIters) && (abs(f1-fn1) >= tolerance)) { // Step 1. Reflection Rule if ((f1<=fr) && (fr<fn)) { for (j=0; j<=N-1; j++) for (i=0; i<=N-1; i++) x[i][j] = y[i][j]; for (i=0; i<=N-1; i++) x[i][N] = xr[i]; goto step0; } // Step 2. Expansion Rule if (fr<f1) { for (j=0; j<=N-1; j++) { for (i=0; i<=N-1; i++) x[i][j] = y[i][j]; } if (fe<fr) for (i=0; i<=N-1; i++) x[i][N] = xe[i]; else for (i=0; i<=N-1; i++) x[i][N] = xr[i]; goto step0; } // Step 3. Outside contraction Rule if ((fn<=fr) && (fr<fn1) && (foc<=fr)) { for (j=0; j<=N-1; j++) { for (i=0; i<=N-1; i++) x[i][j] = y[i][j]; } for (i=0; i<=N-1; i++) x[i][N] = xoc[i]; goto step0; } // Step 4. Inside contraction Rule if ((fr>=fn1) && (fic<fn1)) { for (j=0; j<=N-1; j++) { for (i=0; i<=N-1; i++) x[i][j] = y[i][j]; } for (i=0; i<=N-1; i++) x[i][N] = xic[i]; goto step0; } // Step 5. Shrink Step for (i=0; i<=N-1; i++) x[i][0] = y[i][0]; for (i=0; i<=N-1; i++) { for (j=1; j<=N; j++) x[i][j] = 0.5*(y[i][j] + x[i][0]); } goto step0; } // Output component // Return N parameter values, value of objective function, and number of iterations vector<double> out(N+2); for (i=0; i<=N-1; i++) out[i] = x1[i]; out[N] = f1; out[N+1] = NumIters; return out; }
void Strand2dFCBlockSolver::gradSetupSub(Array3D<double>& gx) { // initialize coefficient array gx.set(0.); // form quadratic sub elements int meshOrderL=2,nElemLocalL=meshOrder-1,nSurfElemL=nSurfElem*nElemLocalL; Array3D<int> surfElemL(nSurfElemL,meshOrderL+1,2); Array3D<int> elemLocalL(nElemLocalL,meshOrderL+1,2); if (meshOrder == 2){ elemLocalL(0,0,0) = 0; elemLocalL(0,0,1) = 1; elemLocalL(0,1,0) = 1; elemLocalL(0,1,1) = 1; elemLocalL(0,2,0) = 2; elemLocalL(0,2,1) = 1; } else if (meshOrder == 3){ elemLocalL(0,0,0) = 0; elemLocalL(0,0,1) = 1; elemLocalL(0,1,0) = 3; elemLocalL(0,1,1) = 0; elemLocalL(0,2,0) = 2; elemLocalL(0,2,1) = 1; elemLocalL(1,0,0) = 2; elemLocalL(1,0,1) = 0; elemLocalL(1,1,0) = 1; elemLocalL(1,1,1) = 1; elemLocalL(1,2,0) = 3; elemLocalL(1,2,1) = 1; } else if (meshOrder == 4){ elemLocalL(0,0,0) = 0; elemLocalL(0,0,1) = 1; elemLocalL(0,1,0) = 3; elemLocalL(0,1,1) = 0; elemLocalL(0,2,0) = 2; elemLocalL(0,2,1) = 1; elemLocalL(1,0,0) = 2; elemLocalL(1,0,1) = 0; elemLocalL(1,1,0) = 4; elemLocalL(1,1,1) = 0; elemLocalL(1,2,0) = 3; elemLocalL(1,2,1) = 1; elemLocalL(2,0,0) = 3; elemLocalL(2,0,1) = 0; elemLocalL(2,1,0) = 1; elemLocalL(2,1,1) = 1; elemLocalL(2,2,0) = 4; elemLocalL(2,2,1) = 1; } int k=0; for (int n=0; n<nSurfElem; n++) for (int i=0; i<nElemLocalL; i++){ for (int m=0; m<meshOrderL+1; m++){ surfElemL(k,m,0) = surfElem(n,elemLocalL(i,m,0)); surfElemL(k,m,1) = elemLocalL(i,m,1); } k++; } if (k != nSurfElemL){ cout << "\n***Problem forming sub-elements in initialize.C***" << endl; exit(0); } // Lagrange polynomial derivatives for lower order elements int spacing=0; // assume equally spaced points in surface elements for now Array1D<double> ss(meshOrderL+1); solutionPoints1D(meshOrderL, spacing, &ss(0)); bool test=false; Array2D<double> lc(meshOrderL+1,meshOrderL+1); lagrangePoly1D(test, // coefficients to form Lagrange polynomials meshOrderL, &ss(0), &lc(0,0)); // ls(i,j) = (dl_j/ds)_i (a row is all Lagrange polynomials (derivatives) // evaluated at a single mesh point i) Array2D<double> lsL(meshOrderL+1,meshOrderL+1); lsL.set(0.); int km; for (int i=0; i<meshOrderL+1; i++) // ith mesh point for (int j=0; j<meshOrderL+1; j++) // jth Lagrange polynomial for (int k=0; k<meshOrderL+1; k++){ km = max(0,k-1); lsL(i,j) +=((double)k)*pow(ss(i),km)*lc(j,k); } // mapping terms for lower order elements Array3D<double> xsL(nSurfElemL,meshOrderL+1,nStrandNode); Array3D<double> ysL(nSurfElemL,meshOrderL+1,nStrandNode); Array3D<double> jacL(nSurfElemL,meshOrderL+1,nStrandNode); xsL.set(0.); ysL.set(0.); int ni,nm; double x0,y0,nx,ny; for (int n=0; n<nSurfElemL; n++) for (int i=0; i<meshOrderL+1; i++){ // ith point in the element ni = surfElemL(n,i,0); for (int m=0; m<meshOrderL+1; m++){ // mth Lagrange poly. in mapping nm = surfElemL(n,m,0); x0 = surfX(nm,0); y0 = surfX(nm,1); nx = pointingVec(nm,0); ny = pointingVec(nm,1); for (int j=0; j<nStrandNode; j++){ xsL(n,i,j) += lsL(i,m)*(x0+nx*strandX(j)); ysL(n,i,j) += lsL(i,m)*(y0+ny*strandX(j)); }} for (int j=0; j<nStrandNode; j++) jacL(n,i,j) = xsL(n,i,j)*yn(ni,j)-ysL(n,i,j)*xn(ni,j); } // degree at each surface node Array1D<int> sum(nSurfNode); sum.set(0); for (int n=0; n<nSurfElemL; n++) for (int i=0; i<meshOrderL+1; i++) sum(surfElemL(n,i,0)) += surfElemL(n,i,1); // use elements to form gradient coefficients double xnj,ynj; Array3D<double> a(nSurfNode,nStrandNode,2); a.set(0.); for (int n=0; n<nSurfElemL; n++) for (int i=0; i<meshOrderL+1; i++){ //ith point in the element if (surfElemL(n,i,1) == 1){ //if a contributing node ni = surfElemL(n,i,0); for (int m=0; m<meshOrderL+1; m++){ //mth Lagrange poly. in mapping nm = surfElemL(n,m,0); for (int j=0; j<nStrandNode; j++){ //local gradient coefficients xnj = xn(ni,j)/(jacL(n,i,j)*(double)sum(ni)); ynj = yn(ni,j)/(jacL(n,i,j)*(double)sum(ni)); a(nm,j,0) = lsL(i,m)*ynj; a(nm,j,1) =-lsL(i,m)*xnj; }} for (int m=psp2(ni); m<psp2(ni+1); m++){ //add to coefficient array nm = psp1(m); for (int j=0; j<nStrandNode; j++){ gx(m,j,0) += a(nm,j,0); gx(m,j,1) += a(nm,j,1); }} for (int m=0; m<meshOrderL+1; m++){ //reset helper array to zero nm = surfElemL(n,m,0); for (int j=0; j<nStrandNode; j++){ a(nm,j,0) = 0.; a(nm,j,1) = 0.; }}}} // clean up sum.deallocate(); a.deallocate(); surfElemL.deallocate(); elemLocalL.deallocate(); xsL.deallocate(); ysL.deallocate(); ss.deallocate(); lc.deallocate(); lsL.deallocate(); }