int minCut(string s) { int n = s.size(); // number of cuts for the first i characters vector<int> cuts(n + 1); for(int i = 0; i < n + 1; i++) { cuts[i] = i - 1; } for(int i = 0; i < n; i++) { // odd palindrome for(int j = 0; i-j >= 0 && i+j < n && s[i-j] == s[i+j]; j++) { // 0 [1 2 3 4 5] 6 7 // (i-j) i (i+j)+1 cuts[(i+j) + 1] = min(cuts[(i-j)] + 1, cuts[(i+j) + 1]); } // even palindrome for(int j = 0; i-j >= 0 && i+j+1 < n && s[i-j] == s[i+j+1]; j++) { // 0 [1 2 3 4 5 6] 7 // (i-j) i (i+j+1)+1 cuts[(i+j+1) + 1] = min(cuts[(i-j)] + 1, cuts[(i+j+1) + 1]); } } return cuts.back(); }
int minCut(string s) { int n = s.length(); vector<vector<bool> > is_pal(n+1, vector<bool>(n+1, false)); init(s, is_pal); vector<int> cuts(n+1, -1); cuts[0] = 0; for (int i = 1; i <= n; ++i) for (int j = i-1; j >= 0; --j) if (is_pal[j][i]) { if (cuts[i] < 0) cuts[i] = cuts[j] + 1; else if (cuts[i] > cuts[j] + 1) cuts[i] = cuts[j] + 1; } return cuts[n]-1; }
void Fit3D::ntupleLoopCore(const int& entry_id) { x_value_ = l0_pcm + l1_pcm; y_value_ = cos_thta; if (evt_sign != 0) { z_value_ = abs(l0_ip_dz - l1_ip_dz); } else { z_value_ = l0_ip_dz - l1_ip_dz; } AnalysisSelectors cuts(*this); fillDataSet(cuts.signal_type()); fillHistograms(cuts.signal_type()); }
KCheckAccelerators::KCheckAccelerators( QObject* parent ) : QObject( parent, "kapp_accel_filter" ), key(0), block( false ), drklash(0) { parent->installEventFilter( this ); KConfigGroupSaver saver( KGlobal::config(), "Development" ); QString sKey = KGlobal::config()->readEntry( "CheckAccelerators" ).stripWhiteSpace(); if( !sKey.isEmpty() ) { KShortcut cuts( sKey ); if( cuts.count() > 0 ) key = int(cuts.seq(0).qt()); } alwaysShow = KGlobal::config()->readBoolEntry( "AlwaysShowCheckAccelerators", false ); autoCheck = KGlobal::config()->readBoolEntry( "AutoCheckAccelerators", true ); connect( &autoCheckTimer, SIGNAL( timeout()), SLOT( autoCheckSlot())); }
std::vector<unsigned> edgeCut(GGraph& g, unsigned nparts) { std::vector<unsigned> cuts(nparts); //find boundary nodes with positive gain for (auto nn = g.begin(), en = g.end(); nn != en; ++nn) { unsigned gPart = g.getData(*nn).getPart(); for (auto ii = g.edge_begin(*nn), ee = g.edge_end(*nn); ii != ee; ++ii) { auto& m = g.getData(g.getEdgeDst(ii)); if (m.getPart() != gPart) { cuts.at(gPart) += g.getEdgeData(ii); } } } return cuts; }
// reduce extra space: O(n) // ??? int minCut_2(string s) { int n = s.size(); vector<int> cuts(n + 1); vector<bool> canCut(n, true); cuts[n] = -1; for (int i = n - 1; i >= 0; --i) { cuts[i] = cuts[i + 1] + 1; for (int j = n - 1; j >= i; --j) { canCut[j] = (s[i] == s[j]) && (j - i < 2 || canCut[j - 1]); if (canCut[j]) { cuts[i] = min(cuts[i], cuts[j + 1] + 1); } } } return cuts[0]; }
int main (int argc, char **argv) { IloEnv env; try { IloModel model(env); IloCplex cplex(env); if ( argc != 2 ) { usage (argv[0]); throw(-1); } IloObjective obj; IloNumVarArray var(env); IloRangeArray rng(env); IloSOS1Array sos1(env); IloSOS2Array sos2(env); IloRangeArray lazy(env); IloRangeArray cuts(env); cplex.importModel(model, argv[1], obj, var, rng, sos1, sos2, lazy, cuts); cplex.extract(model); if ( lazy.getSize() > 0 ) cplex.addLazyConstraints (lazy); if ( cuts.getSize() > 0 ) cplex.addUserCuts (cuts); cplex.solve(); env.out() << "Solution status = " << cplex.getStatus() << endl; env.out() << "Solution value = " << cplex.getObjValue() << endl; IloNumArray vals(env); cplex.getValues(vals, var); env.out() << "Values = " << vals << endl; } catch (IloException& e) { cerr << "Concert exception caught: " << e << endl; } catch (...) { cerr << "Unknown exception caught" << endl; } env.end(); return 0; } // END main
// time : O(n^2) // space : O(n^2) int minCut(string s) { int n = s.size(); vector<int> cuts(n + 1, 0); cuts[0] = -1; vector<vector<bool> > canCut(n, vector<bool>(n, false)); for (int i = 1; i <= n; ++i) { cuts[i] = i - 1; for (int j = i; j >= 1; --j) { // j...i canCut[j - 1][i - 1] = (s[i - 1] == s[j - 1]) && (i - j < 2 || canCut[j][i - 2]); if (canCut[j - 1][i - 1]) { cuts[i] = min(cuts[i], cuts[j - 1] + 1); } } } return cuts[n]; }
int main(int argc, char** argv) { IloEnv env; try { IloModel m(env); IloCplex cplex(env); IloObjective obj; IloNumVarArray vars(env); IloRangeArray rngs(env); const char* datadir = (argc >= 2) ? argv[1] : "../../../examples/data"; char *fname = new char[strlen(datadir) + 1 + strlen("noswot.mps") + 1]; sprintf(fname, "%s/noswot.mps", datadir); env.out() << "reading " << fname << endl; cplex.importModel(m, fname, obj, vars, rngs); delete[] fname; env.out() << "extracting model ..." << endl; cplex.extract(m); IloRangeArray cuts(env); makeCuts(cuts, vars); // Use addUserCuts when the added constraints strengthen the // formulation. Use addLazyConstraints when the added constraints // remove part of the feasible region. Use addCuts when you are // not certain. cplex.addUserCuts(cuts); cuts.endElements(); cuts.end(); cplex.setParam(IloCplex::Param::MIP::Interval, 1000); env.out() << "solving model ...\n"; cplex.solve(); env.out() << "solution status is " << cplex.getStatus() << endl; env.out() << "solution value is " << cplex.getObjValue() << endl; } catch (IloException& ex) { cerr << "Error: " << ex << endl; } env.end(); return 0; }
int minCut(string s) { // Start typing your C/C++ solution below // DO NOT write int main() function int n = s.size(); if(!n) return 0; vector<vector<bool> > f(n,vector<bool>(n,false)); for(int i = n-1;i >= 0;i--) { for(int j = i;j < n;j++) { if(s[i]==s[j]) { if(j-i<3) f[i][j]=true; else f[i][j]=f[i+1][j-1]; } } } vector<vector<int> > next(n); for(int i = 0;i < n;i++) { for(int j = i;j < n;j++) { if(f[i][j]) next[i].push_back(j); } } f.clear(); vector<int> cuts(n,INT_MAX); for(int i = n-1;i >= 0;i--) { for(int j = 0;j < next[i].size();j++) { int cut; if(next[i][j] = n-1) cut = 1; else cut = 1+cuts[next[i][j]+1]; if(cut<cuts[i]) cuts[i] = cut; } } return cuts[0]; }
// Process the strongly connected components of the graph. We only work // on the largest SCC. void CommDetection::ProcessSCCs() { Network& net = CurrNetwork(); TCnComV components; TSnap::GetSccs(net.graph(), components); if (components.Len() == 1) { return; } int num_scc = components.Len(); std::vector< std::vector<int> > cuts(num_scc); for (int j = 0; j < num_scc; ++j) { TCnCom comp = components[j]; std::vector<int>& curr_cut = cuts[j]; for (int i = 0; i < comp.Len(); ++i) { curr_cut.push_back(comp[i].Val); } } // Find the largest remaining component int argmax_ind = -1; int max_val = -1; for (int i = 0; i < cuts.size(); ++i) { if (max_val == -1 || cuts[i].size() > max_val) { argmax_ind = i; max_val = cuts[i].size(); } } // Now we cut out each component std::cout << "Removing SCC" << std::endl; Cutter cutter(net, algorithm_, cut_type_, ""); RemoveCutFromCurrNetwork(cutter, cuts[argmax_ind]); // TODO(arbenson): this is kindof a hack for dealing with SCCs. We don't // want to process all of them because there are many isolated nodes. // Instead, we continue processing until the largest community (in terms // of the number of nodes) is a SCC. ProcessSCCs(); }
Foam::Map<Foam::label> Foam::refinementIterator::setRefinement ( const List<refineCell>& refCells ) { Map<label> addedCells(2*refCells.size()); Time& runTime = const_cast<Time&>(mesh_.time()); label nRefCells = refCells.size(); label oldRefCells = -1; // Operate on copy. List<refineCell> currentRefCells(refCells); bool stop = false; do { if (writeMesh_) { // Need different times to write meshes. runTime++; } polyTopoChange meshMod(mesh_); if (debug) { Pout<< "refinementIterator : refining " << currentRefCells.size() << " cells." << endl; } // Determine cut pattern. cellCuts cuts(mesh_, cellWalker_, currentRefCells); label nCuts = cuts.nLoops(); reduce(nCuts, sumOp<label>()); if (nCuts == 0) { if (debug) { Pout<< "refinementIterator : exiting iteration since no valid" << " loops found for " << currentRefCells.size() << " cells" << endl; fileName cutsFile("failedCuts_" + runTime.timeName() + ".obj"); Pout<< "Writing cuts for time " << runTime.timeName() << " to " << cutsFile << endl; OFstream cutsStream(cutsFile); labelList refCellsDebug(currentRefCells.size()); forAll(currentRefCells, i) { refCellsDebug[i] = currentRefCells[i].cellNo(); } meshTools::writeOBJ ( cutsStream, mesh().cells(), mesh().faces(), mesh().points(), refCellsDebug ); } break; } if (debug) { fileName cutsFile("cuts_" + runTime.timeName() + ".obj"); Pout<< "Writing cuts for time " << runTime.timeName() << " to " << cutsFile << endl; OFstream cutsStream(cutsFile); cuts.writeOBJ(cutsStream); } // Insert mesh refinement into polyTopoChange. meshRefiner_.setRefinement(cuts, meshMod); // // Do all changes // autoPtr<mapPolyMesh> morphMap = meshMod.changeMesh ( mesh_, false ); // Move mesh (since morphing does not do this) if (morphMap().hasMotionPoints()) { mesh_.movePoints(morphMap().preMotionPoints()); } // Update stored refinement pattern meshRefiner_.updateMesh(morphMap()); // Write resulting mesh if (writeMesh_) { if (debug) { Pout<< "Writing refined polyMesh to time " << runTime.timeName() << endl; } mesh_.write(); } // Update currentRefCells for new cell numbers. Use helper function // in meshCutter class. updateLabels ( morphMap->reverseCellMap(), currentRefCells ); // Update addedCells for new cell numbers updateLabels ( morphMap->reverseCellMap(), addedCells ); // Get all added cells from cellCutter (already in new numbering // from meshRefiner.updateMesh call) and add to global list of added const Map<label>& addedNow = meshRefiner_.addedCells(); forAllConstIter(Map<label>, addedNow, iter) { if (!addedCells.insert(iter.key(), iter())) { FatalErrorInFunction << "Master cell " << iter.key() << " already has been refined" << endl << "Added cell:" << iter() << abort(FatalError); } } // Get failed refinement in new cell numbering and reconstruct input // to the meshRefiner. Is done by removing all refined cells from // current list of cells to refine. // Update refCells for new cell numbers. updateLabels ( morphMap->reverseCellMap(), currentRefCells ); // Pack refCells acc. to refined status nRefCells = 0; forAll(currentRefCells, refI) { const refineCell& refCell = currentRefCells[refI]; if (!addedNow.found(refCell.cellNo())) { if (nRefCells != refI) { currentRefCells[nRefCells++] = refineCell ( refCell.cellNo(), refCell.direction() ); } } } oldRefCells = currentRefCells.size(); currentRefCells.setSize(nRefCells); if (debug) { Pout<< endl; } // Stop only if all finished or all can't refine any further. stop = (nRefCells == 0) || (nRefCells == oldRefCells); reduce(stop, andOp<bool>()); } while (!stop); if (nRefCells == oldRefCells) { WarningInFunction << "stopped refining." << "Did not manage to refine a single cell" << endl << "Wanted :" << oldRefCells << endl; } return addedCells; }
int main (int argc, char **argv) { char const *vmconfig = NULL; // Check command line length (exactly two arguments are required). if ( argc != 3 ) { usage (argv[0]); return -1; } // Pick up VMC from command line. vmconfig = argv[1]; // Solve the model. int exitcode = 0; IloEnv env; try { // Create and read the model. IloModel model(env); IloCplex cplex(model); IloObjective obj; IloNumVarArray var(env); IloRangeArray rng(env); IloSOS1Array sos1(env); IloSOS2Array sos2(env); IloRangeArray lazy(env); IloRangeArray cuts(env); cplex.importModel(model, argv[2], obj, var, rng, sos1, sos2, lazy, cuts); cplex.extract(model); if ( lazy.getSize() > 0 ) cplex.addLazyConstraints (lazy); if ( cuts.getSize() > 0 ) cplex.addUserCuts (cuts); // Load the virtual machine configuration. // This will force solve() to use parallel distributed MIP. cplex.readVMConfig(vmconfig); // Install logging info callback. IloNum lastObjVal = (obj.getSense() == IloObjective::Minimize ) ? IloInfinity : -IloInfinity; cplex.use(loggingCallback(env, var, -100000, lastObjVal, cplex.getCplexTime(), cplex.getDetTime())); // Turn off CPLEX logging cplex.setParam(IloCplex::Param::MIP::Display, 0); // Solve the problem and display some results. if ( cplex.solve() ) env.out() << "Solution value = " << cplex.getObjValue() << endl; else env.out() << "No solution" << endl; env.out() << "Solution status = " << cplex.getStatus() << endl; // Cleanup. cplex.end(); model.end(); } catch (IloException& e) { cerr << "Concert exception caught: " << e << endl; exitcode = -1; } catch (...) { cerr << "Unknown exception caught" << endl; exitcode = -1; } env.end(); return exitcode; } // END main
std::vector<std::tuple<boost::dynamic_bitset<>, unsigned, boost::dynamic_bitset<>>> mig_cuts_paged::enumerate_local_cuts( mig_node n1, mig_node n2, mig_node n3, unsigned max_cut_size ) { std::vector<std::tuple<boost::dynamic_bitset<>, unsigned, boost::dynamic_bitset<>>> local_cuts; for ( const auto& c1 : boost::combine( cuts( n1 ), cut_cones( n1 ) ) ) { for ( const auto& c2 : boost::combine( cuts( n2 ), cut_cones( n2 ) ) ) { for ( const auto& c3 : boost::combine( cuts( n3 ), cut_cones( n3 ) ) ) { auto min_level = std::numeric_limits<unsigned>::max(); boost::dynamic_bitset<> new_cut( max_cut_size ); auto f = [&new_cut, &min_level, this]( unsigned pos ) { new_cut.set( pos ); min_level = std::min( min_level, this->_levels[pos].second ); }; std::for_each( boost::get<0>( c1 ).begin(), boost::get<0>( c1 ).end(), f ); std::for_each( boost::get<0>( c2 ).begin(), boost::get<0>( c2 ).end(), f ); std::for_each( boost::get<0>( c3 ).begin(), boost::get<0>( c3 ).end(), f ); boost::dynamic_bitset<> new_cone( max_cut_size ); auto f2 = [&new_cone]( unsigned pos ) { new_cone.set( pos ); }; std::for_each( boost::get<1>( c1 ).begin(), boost::get<1>( c1 ).end(), f2 ); std::for_each( boost::get<1>( c2 ).begin(), boost::get<1>( c2 ).end(), f2 ); std::for_each( boost::get<1>( c3 ).begin(), boost::get<1>( c3 ).end(), f2 ); /* too large? */ if ( new_cut.count() > _k ) { continue; } auto first_subsume = true; auto add = true; auto l = 0u; while ( l < local_cuts.size() ) { auto cut = std::get<0>( local_cuts[l] ); /* same cut */ if ( cut == new_cut ) { add = false; break; } /* cut subsumes new_cut */ if ( ( cut & new_cut ) == new_cut ) { add = false; break; } /* new_cut subsumes cut */ if ( ( cut & new_cut ) == cut ) { add = false; if ( first_subsume ) { local_cuts[l] = std::make_tuple( new_cut, min_level, new_cone ); first_subsume = false; } else { local_cuts[l] = local_cuts.back(); local_cuts.pop_back(); } } ++l; } if ( add ) { local_cuts += std::make_tuple( new_cut, min_level, new_cone ); } } } } boost::sort( local_cuts, []( const std::tuple<boost::dynamic_bitset<>, unsigned, boost::dynamic_bitset<>>& e1, const std::tuple<boost::dynamic_bitset<>, unsigned, boost::dynamic_bitset<>>& e2 ) { return ( std::get<1>( e1 ) > std::get<1>( e2 ) ) || ( std::get<1>( e1 ) == std::get<1>( e2 ) && std::get<0>( e1 ).count() < std::get<0>( e2 ).count() ); } ); if ( local_cuts.size() > _priority ) { local_cuts.resize( _priority ); } return local_cuts; }
int main (int argc, char **argv) { IloEnv env; try { IloModel model(env); IloCplex cplex(env); if ( argc != 2 ) { usage (argv[0]); throw(-1); } IloObjective obj; IloNumVarArray var(env); IloRangeArray rng(env); IloSOS1Array sos1(env); IloSOS2Array sos2(env); IloRangeArray lazy(env); IloRangeArray cuts(env); cplex.importModel(model, argv[1], obj, var, rng, sos1, sos2, lazy, cuts); /* Set the solution pool relative gap parameter to obtain solutions of objective value within 10% of the optimal */ cplex.setParam(IloCplex::Param::MIP::Pool::RelGap, 0.1); cplex.extract(model); if ( lazy.getSize() > 0 ) cplex.addLazyConstraints(lazy); if ( cuts.getSize() > 0 ) cplex.addUserCuts(cuts); cplex.populate(); env.out() << "Solution status = " << cplex.getStatus() << endl; env.out() << "Incumbent objective value = " << cplex.getObjValue() << endl; IloNumArray incvals(env); cplex.getValues(incvals, var); env.out() << "Incumbent values = " << incvals << endl << endl; /* Get the number of solutions in the solution pool */ int numsol = cplex.getSolnPoolNsolns(); env.out() << "The solution pool contains " << numsol << " solutions." << endl; /* Some solutions are deleted from the pool because of the solution pool relative gap parameter */ int numsolreplaced = cplex.getSolnPoolNreplaced(); env.out() << numsolreplaced << " solutions were removed due to the " "solution pool relative gap parameter." << endl; env.out() << "In total, " << numsol + numsolreplaced << " solutions were generated." << endl; /* Get the average objective value of solutions in the solution pool */ env.out() << "The average objective value of the solutions is " << cplex.getSolnPoolMeanObjValue() << "." << endl << endl; /* Write out the objective value of each solution and its difference to the incumbent */ for (int i = 0; i < numsol; i++) { /* Write out objective value */ env.out() << "Solution " << i << " with objective " << cplex.getObjValue(i) << " differs in "; IloNumArray vals(env); cplex.getValues(vals, var, i); /* Compute the number of variables that differ in the solution and in the incumbent */ int numdiff = 0; for (int j = 0; j < vals.getSize(); j++) { if ( fabs(vals[j] - incvals[j]) > EPSZERO ) numdiff++; } env.out() << numdiff << " of " << vals.getSize() << " variables." << endl; } } catch (IloException& e) { cerr << "Concert exception caught: " << e << endl; } catch (...) { cerr << "Unknown exception caught" << endl; } env.end(); return 0; } // END main
int solveCplex (char * str,ListStructure<number_element> * l) { IloEnv env; try { IloModel model(env); IloCplex cplex(env); IloObjective obj; IloNumVarArray var(env); IloRangeArray rng(env); IloSOS1Array sos1(env); IloSOS2Array sos2(env); IloRangeArray lazy(env); IloRangeArray cuts(env); cplex.importModel(model, str, obj, var, rng, sos1, sos2, lazy, cuts); cplex.use(MyBranch(env, var)); cplex.use(MySelect(env)); cplex.setParam(IloCplex::MIPSearch, IloCplex::Traditional); cplex.extract(model); cplex.setParam(IloCplex::EpInt,0.000000000001); cplex.setParam(IloCplex::TiLim,120*60); if ( lazy.getSize() > 0 ) cplex.addLazyConstraints (lazy); if ( cuts.getSize() > 0 ) cplex.addUserCuts (cuts); cplex.solve(); env.out() << "Solution status = " << cplex.getStatus() << endl; env.out() << "Solution value = " << cplex.getObjValue() << endl; IloNumArray vals(env); cplex.getValues(vals, var); //IloObjective obj=cplex.getObjective(); env.out() << "Values = " << vals << endl; long long sum=0; int a=vals.getSize(); for(int i=0;i<a;i++){ int b=l->getSize(); number_element n=l->retrieve_K_esimo(i%b)->element; if(i<b){ if(vals[i]>0.9){ sum+=n.id; } }else{ if(vals[i]>0.9){ sum-=n.id; } } } } catch (IloException& e) { cerr << "Concert exception caught: " << e << endl; } catch (...) { cerr << "Unknown exception caught" << endl; } env.end(); } // END main
int main (int argc, char **argv) { IloEnv env; try { IloModel model(env); IloCplex cplex(env); IloBool useLoggingCallback = IloFalse; IloBool useTimeLimitCallback = IloFalse; IloBool useAborter = IloFalse; if (( argc != 3 ) || ( strchr ("lat", argv[2][0]) == NULL ) ) { usage (argv[0]); throw(-1); } switch (argv[2][0]) { case 'l': useLoggingCallback = IloTrue; break; case 't': useTimeLimitCallback = IloTrue; break; case 'a': useAborter = IloTrue; break; default: break; } IloObjective obj; IloNumVarArray var(env); IloRangeArray rng(env); IloSOS1Array sos1(env); IloSOS2Array sos2(env); IloRangeArray lazy(env); IloRangeArray cuts(env); IloCplex::Aborter myAborter; cplex.importModel(model, argv[1], obj, var, rng, sos1, sos2, lazy, cuts); cplex.extract(model); if ( lazy.getSize() > 0 ) cplex.addLazyConstraints (lazy); if ( cuts.getSize() > 0 ) cplex.addUserCuts (cuts); if ( useLoggingCallback ) { // Set an overall node limit in case callback conditions // are not met. cplex.setParam(IloCplex::Param::MIP::Limits::Nodes, 5000); IloNum lastObjVal = (obj.getSense() == IloObjective::Minimize ) ? IloInfinity : -IloInfinity; cplex.use(loggingCallback(env, var, -100000, lastObjVal, cplex.getCplexTime(), cplex.getDetTime())); // Turn off CPLEX logging cplex.setParam(IloCplex::Param::MIP::Display, 0); } else if ( useTimeLimitCallback ) { cplex.use(timeLimitCallback(env, cplex, IloFalse, cplex.getCplexTime(), 1.0, 10.0)); } else if ( useAborter ) { myAborter = IloCplex::Aborter(env); cplex.use(myAborter); // Typically, you would pass the Aborter object to // another thread or pass it to an interrupt handler, // and monitor for some event to occur. When it does, // call the Aborter's abort method. // // To illustrate its use without creating a thread or // an interrupt handler, abort immediately by calling // abort before the solve. // myAborter.abort(); } cplex.solve(); env.out() << endl; env.out() << "Solution status = " << cplex.getStatus() << endl; env.out() << "CPLEX status = " << cplex.getCplexStatus() << endl; } catch (IloException& e) { cerr << "Concert exception caught: " << e << endl; } catch (...) { cerr << "Unknown exception caught" << endl; } env.end(); return 0; } // END main
Foam::plane Foam::sweptFaceAreaWeightAMI<SourcePatch, TargetPatch>::getCutPlane ( const point& p0, const point& p1, const vector& n0, const vector& n1, const FixedList<point, 3>& tgtTri ) const { // The target plane const plane tgtPln(tgtTri[0], tgtTri[1], tgtTri[2]); const point& pp = tgtPln.refPoint(); const vector& np = tgtPln.normal(); // Calculate the bounding intersection points. These are the locations at // which the bounding lines of the projected surface intersect with the // target plane. const scalar v0 = ((pp - p0) & np)/(n0 & np); const scalar v1 = ((pp - p1) & np)/(n1 & np); Pair<point> cutPnts(p0 + v0*n0, p1 + v1*n1); Pair<vector> cutNrms((p1 - p0 + n1*v0) ^ n0, (p1 - p0 - n0*v1) ^ n1); // Calculate edge intersections with the surface for (label i = 0; i < 3; ++ i) { // The current target edge const point& l0 = tgtTri[i], l1 = tgtTri[(i + 1)%3]; // Form the quadratic in the surface parameter u const vector k = l0 - p0; const vector a = l0 - l1, b = p1 - p0, c = n0, d = n1 - n0; const vector ka = k ^ a, ba = b ^ a, ca = c ^ a, da = d ^ a; const scalar A = d & ba; const scalar B = (c & ba) - (d & ka); const scalar C = - c & ka; // Solve and extract the other parameters const Roots<2> us = quadraticEqn(A, B, C).roots(); Pair<scalar> vs, ws; Pair<vector> ns; Pair<bool> cuts(false, false); for (label j = 0; j < 2; ++ j) { if (us.type(j) == rootType::real) { const vector den = ca + da*us[j]; if (magSqr(den) > vSmall) { const vector vNum = ka - ba*us[j]; const vector wNum = (- k + b*us[j]) ^ (c + d*us[j]); vs[j] = (vNum & den)/magSqr(den); ws[j] = (wNum & den)/magSqr(den); ns[j] = (b ^ (c + d*us[j])) + (n1 ^ n0)*vs[j]; const bool cutu = 0 < us[j] && us[j] < 1; const bool cutw = 0 < ws[j] && ws[j] < 1; cuts[j] = cutu && cutw; } } } // If we have just one intersection in bounds then store it in the // result list based on its direction if (cuts[0] != cuts[1]) { const label j = cuts[0] ? 0 : 1; const scalar na = ns[j] & a; cutPnts[na < 0] = l0 + (l1 - l0)*ws[j]; cutNrms[na < 0] = ns[j]; } } // Generate and return the cut plane. If the cut points are not coincident // then form a plane normal by crossing the displacement between the points // by the target plane normal. If the points are coincident then use the // projected surface normal evaluated at the first cut point. const vector cutDelta = cutPnts[1] - cutPnts[0]; const bool coincident = mag(cutDelta) < minCutRatio_*mag(p1 - p0); return plane(cutPnts[0], coincident ? cutNrms[0] : np ^ cutDelta); };