@@ -1267,6 +1267,91 @@ LNLib::UV LNLib::NurbsSurface::GetParamOnSurface(const LN_NurbsSurface& surface,
12671267 return param;
12681268}
12691269
1270+ LNLib::UV LNLib::NurbsSurface::GetParamOnSurfaceByGSA (const LN_NurbsSurface& surface, const XYZ& givenPoint)
1271+ {
1272+ std::vector<double > knotVectorU = surface.KnotVectorU ;
1273+ std::vector<double > knotVectorV = surface.KnotVectorV ;
1274+
1275+ double minU = knotVectorU[0 ];
1276+ double maxU = knotVectorU[knotVectorU.size () - 1 ];
1277+ double minV = knotVectorV[0 ];
1278+ double maxV = knotVectorV[knotVectorV.size () - 1 ];
1279+
1280+ double u0 = (maxU - minU) * 0.5 ;
1281+ double v0 = (maxV - minV) * 0.5 ;
1282+
1283+ int counter = 0 ;
1284+
1285+ while (counter < 1000 )
1286+ {
1287+ LNLib::UV initialUV = UV (u0, v0);
1288+ XYZ p0 = GetPointOnSurface (surface, initialUV);
1289+ XYZ normal = Normal (surface, initialUV);
1290+
1291+ std::vector<std::vector<XYZ>> ders = ComputeRationalSurfaceDerivatives (surface, 2 , initialUV);
1292+ XYZ Suu = ders[2 ][0 ];
1293+ XYZ Svv = ders[0 ][2 ];
1294+ XYZ Suv = ders[1 ][1 ];
1295+
1296+ XYZ Su = ders[1 ][0 ];
1297+ XYZ Sv = ders[0 ][1 ];
1298+
1299+ double L = Suu.DotProduct (normal);
1300+ double M = Suv.DotProduct (normal);
1301+ double N = Svv.DotProduct (normal);
1302+ double E = Su.DotProduct (Su);
1303+ double F = Su.DotProduct (Sv);
1304+ double G = Sv.DotProduct (Sv);
1305+ double denominator = E * G - F * F;
1306+
1307+ if (MathUtils::IsAlmostEqualTo (denominator, 0.0 ))
1308+ {
1309+ return UV (Constants::DoubleEpsilon, Constants::DoubleEpsilon);
1310+ }
1311+
1312+ double c1 = Su.DotProduct (normal);
1313+ double c2 = Sv.DotProduct (normal);
1314+ double c3 = 1 ;
1315+ double s1 = (givenPoint - p0).DotProduct (Su);
1316+ double s2 = (givenPoint - p0).DotProduct (Sv);
1317+ double s3 = (givenPoint - p0).DotProduct (normal);
1318+
1319+ double a1 = - (c1 * c2 * s2 - c1 * G * s3 - c2 * c2 * s1 + c2 * F * s3 - F * s2 + G * s1 )/(c1 * c1 * G - 2 * c1 * c2 * F + c2 * c2 * E - E * G + F * F);
1320+ double a2 = (c1 * c1 * s2 - c1 * c2 * s1 - c1 * F * s3 + c2 * E * s3 - E * s2 + F * s1)/(c1 * c1 * G - 2 * c1 * c2 * F + c2 * c2 * E - E * G + F * F);
1321+
1322+ double curvature = (L * a1 * a1 + 2 * M * a1* a2 + N * a2 * a2)/(E * a1 * a1 + 2 * F * a1 * a2 + G * a2 * a2);
1323+ double radius = 1 / abs (curvature);
1324+
1325+ XYZ m = p0 + radius * normal;
1326+ XYZ q = givenPoint + (m - givenPoint) * (1 - radius / (m.Distance (givenPoint)));
1327+
1328+ double c4 = (q - p0).DotProduct (Su);
1329+ double c5 = (q - p0).DotProduct (Sv);
1330+
1331+ double deltaU = (c4 * G - c5 * F) / denominator;
1332+ double deltaV = -(c4 * F - c5 * E) / denominator;
1333+
1334+ double ut = u0 + deltaU;
1335+ double vt = v0 + deltaV;
1336+
1337+ u0 = ut;
1338+ v0 = vt;
1339+
1340+ if (MathUtils::IsLessThanOrEqual (abs (deltaU), Constants::DoubleEpsilon) &&
1341+ MathUtils::IsLessThanOrEqual (abs (deltaV), Constants::DoubleEpsilon))
1342+ {
1343+ LNLib::UV newUV = UV (ut, vt);
1344+ XYZ newNormal = Normal (surface, newUV);
1345+ if (normal.IsAlmostEqualTo (newNormal))
1346+ {
1347+ break ;
1348+ }
1349+ }
1350+ counter++;
1351+ }
1352+ return UV (u0, v0);
1353+ }
1354+
12701355void LNLib::NurbsSurface::Reparametrize (const LN_NurbsSurface& surface, double minU, double maxU, double minV, double maxV, LN_NurbsSurface& result)
12711356{
12721357 std::vector<double > knotVectorU = surface.KnotVectorU ;
0 commit comments