Advertisement
Guest User

Untitled

a guest
Jan 19th, 2017
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.96 KB | None | 0 0
  1.     std::vector<kernel::Vector> findBoundingPoints(kernel::Arc const& value)
  2.     {
  3.         PSVector start  = value.start,
  4.                  middle = value.middle,
  5.                  end    = value.end;
  6.         EXPECT(start != middle && middle != end, "points which define arc must not coincide");
  7.  
  8.         auto t = middle - start,
  9.              u = end    - start,
  10.              v = end    - middle;
  11.  
  12.         auto w = t.cross(u);
  13.         EXPECT(!w.isZero(), "points must define a plane in order to form an arc");
  14.  
  15.         // Calculate the center of the circumscribed circle
  16.         auto center = start + (u * t.dot(t) * u.dot(v) - t * u.dot(u) * t.dot(v)) / (w.dot(w) * 2.0);
  17.         auto s = start - center;
  18.         auto e = end - center;
  19.  
  20.         // X vector is taken as pointing to the starting point
  21.         // This way the parameter of the start is always zero
  22.         auto x = s.normalized();
  23.         auto y = w.cross(s).normalized();
  24.  
  25.         // Angle between start and end points is the parameter of the end point
  26.         double se = atan2(s.cross(e).length(), s.dot(e));
  27.         if (se < 0)
  28.             se += M_PI * 2;
  29.  
  30.         // Collect all possible parameters of extrema
  31.         // Dividing by zero is fine since it returns inf/-inf and atan(+-inf) is +-Pi/2
  32.         std::vector<double> params {0.0, se};
  33.         if (!math::equalEps(x.x, 0.0)) params.push_back(atan(x.x / y.x));
  34.         if (!math::equalEps(x.y, 0.0)) params.push_back(atan(x.y / y.y));
  35.         if (!math::equalEps(x.z, 0.0)) params.push_back(atan(x.z / y.z));
  36.         for (double par: params) params.push_back(par + M_PI);
  37.  
  38.         // Evaluate points at all extrema parameters that lie between start and end parameters
  39.         std::vector<PSVector> points;
  40.         points.reserve(params.size());
  41.         for (double par: params)
  42.             if (par >= 0.0 && par <= se)
  43.                 points.push_back(center + s.length() * (cos(par) * x + sin(par) * y));
  44.  
  45.         return points;
  46.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement