bool surfacePointWithExclusionRegion::inExclusionZone(const SPoint2 &p) { double mat[2][2]; double b[2], uv[2]; mat[0][0] = _q[1].x() - _q[0].x(); mat[0][1] = _q[2].x() - _q[0].x(); mat[1][0] = _q[1].y() - _q[0].y(); mat[1][1] = _q[2].y() - _q[0].y(); b[0] = p.x() - _q[0].x(); b[1] = p.y() - _q[0].y(); sys2x2(mat, b, uv); // printf("inversion 1 : %g %g \n",uv[0],uv[1]); if(uv[0] >= 0 && uv[1] >= 0 && 1. - uv[0] - uv[1] >= 0) return true; mat[0][0] = _q[3].x() - _q[2].x(); mat[0][1] = _q[0].x() - _q[2].x(); mat[1][0] = _q[3].y() - _q[2].y(); mat[1][1] = _q[0].y() - _q[2].y(); b[0] = p.x() - _q[2].x(); b[1] = p.y() - _q[2].y(); sys2x2(mat, b, uv); // printf("inversion 2 : %g %g \n",uv[0],uv[1]); if(uv[0] >= 0 && uv[1] >= 0 && 1. - uv[0] - uv[1] >= 0) return true; return false; }
GPoint gmshFace::closestPoint(const SPoint3 & qp, const double initialGuess[2]) const { #if defined(HAVE_BFGS) return GFace::closestPoint(qp, initialGuess); #endif if (s->Typ == MSH_SURF_PLAN && !s->geometry){ double XP = qp.x(); double YP = qp.y(); double ZP = qp.z(); double VX[3], VY[3], x, y, z; getMeanPlaneData(VX, VY, x, y, z); double M[3][2] = {{VX[0], VY[0]}, {VX[1], VY[1]}, {VX[2], VY[2]}}; double MN[2][2]; double B[3] = {XP - x, YP - y, ZP - z}; double BN[2], UV[2]; for (int i = 0; i < 2; i++){ BN[i] = 0; for (int k = 0; k < 3; k++){ BN[i] += B[k] * M[k][i]; } } for (int i = 0; i < 2; i++){ for (int j = 0; j < 2; j++){ MN[i][j] = 0; for (int k = 0; k < 3; k++){ MN[i][j] += M[k][i] * M[k][j]; } } } sys2x2(MN, BN, UV); return GPoint(XP, YP, ZP, this, UV); } Vertex v; v.Pos.X = qp.x(); v.Pos.Y = qp.y(); v.Pos.Z = qp.z(); double u[2] = {initialGuess[0], initialGuess[1]}; bool result = ProjectPointOnSurface(s, v, u); if (!result) return GPoint(-1.e22, -1.e22, -1.e22, 0, u); return GPoint(v.Pos.X, v.Pos.Y, v.Pos.Z, this, u); }
bool frameFieldBackgroundMesh2D::compute_RK_infos(double u,double v, double x, double y, double z, RK_form &infos) { // check if point is in domain if (!inDomain(u,v)) return false; // get stored angle double angle_current = angle(u,v); // compute t1,t2: cross field directions // get the unit normal at that point GFace *face = dynamic_cast<GFace*>(gf); if(!face) { Msg::Error("Entity is not a face in background mesh"); return false; } Pair<SVector3, SVector3> der = face->firstDer(SPoint2(u,v)); SVector3 s1 = der.first(); SVector3 s2 = der.second(); SVector3 n = crossprod(s1,s2); n.normalize(); SVector3 basis_u = s1; basis_u.normalize(); SVector3 basis_v = crossprod(n,basis_u); // normalize vector t1 that is tangent to gf at uv SVector3 t1 = basis_u * cos(angle_current) + basis_v * sin(angle_current) ; t1.normalize(); // compute the second direction t2 and normalize (t1,t2,n) is the tangent frame SVector3 t2 = crossprod(n,t1); t2.normalize(); // get metric double L = size(u,v); infos.metricField = SMetric3(1./(L*L)); FieldManager *fields = gf->model()->getFields(); if(fields->getBackgroundField() > 0) { Field *f = fields->get(fields->getBackgroundField()); if (!f->isotropic()) { (*f)(x,y,z, infos.metricField,gf); } else { L = (*f)(x,y,z,gf); infos.metricField = SMetric3(1./(L*L)); } } double M = dot(s1,s1); double N = dot(s2,s2); double E = dot(s1,s2); // compute the first fundamental form i.e. the metric tensor at the point // M_{ij} = s_i \cdot s_j double metric[2][2] = {{M,E},{E,N}}; // get sizes double size_1 = sqrt(1. / dot(t1,infos.metricField,t1)); double size_2 = sqrt(1. / dot(t2,infos.metricField,t2)); // compute covariant coordinates of t1 and t2 - cross field directions in parametric domain double covar1[2],covar2[2]; // t1 = a s1 + b s2 --> // t1 . s1 = a M + b E // t1 . s2 = a E + b N --> solve the 2 x 2 system // and get covariant coordinates a and b double rhs1[2] = {dot(t1,s1),dot(t1,s2)}; bool singular = false; if (!sys2x2(metric,rhs1,covar1)) { Msg::Info("Argh surface %d %g %g %g -- %g %g %g -- %g %g",gf->tag(),s1.x(),s1.y(),s1.z(),s2.x(),s2.y(),s2.z(),size_1,size_2); covar1[1] = 1.0; covar1[0] = 0.0; singular = true; } double rhs2[2] = {dot(t2,s1),dot(t2,s2)}; if (!sys2x2(metric,rhs2,covar2)) { Msg::Info("Argh surface %d %g %g %g -- %g %g %g",gf->tag(),s1.x(),s1.y(),s1.z(),s2.x(),s2.y(),s2.z()); covar2[0] = 1.0; covar2[1] = 0.0; singular = true; } // transform the sizes with respect to the metric // consider a vector v of size 1 in the parameter plane // its length is sqrt (v^T M v) --> if I want a real size // of size1 in direction v, it should be sqrt(v^T M v) * size1 double l1 = sqrt(covar1[0]*covar1[0]+covar1[1]*covar1[1]); double l2 = sqrt(covar2[0]*covar2[0]+covar2[1]*covar2[1]); covar1[0] /= l1; covar1[1] /= l1; covar2[0] /= l2; covar2[1] /= l2; double size_param_1 = size_1 / sqrt ( M*covar1[0]*covar1[0]+ 2*E*covar1[1]*covar1[0]+ N*covar1[1]*covar1[1]); double size_param_2 = size_2 / sqrt ( M*covar2[0]*covar2[0]+ 2*E*covar2[1]*covar2[0]+ N*covar2[1]*covar2[1]); if (singular) { size_param_1 = size_param_2 = std::min (size_param_1,size_param_2); } // filling form... infos.t1 = t1; infos.h.first = size_1; infos.h.second = size_2; infos.paramh.first = size_param_1; infos.paramh.second = size_param_2; infos.paramt1 = SPoint2(covar1[0],covar1[1]); infos.paramt2 = SPoint2(covar2[0],covar2[1]); infos.angle = angle_current; infos.localsize = L; infos.normal = n; return true; }