diff --git a/Device/Detector/Detector2D.cpp b/Device/Detector/Detector2D.cpp
index acab1a51f9bcae65b44824f9d32adde202eee734..cc20d54044f5056ee320ed959c1914f49c7f4c9a 100644
--- a/Device/Detector/Detector2D.cpp
+++ b/Device/Detector/Detector2D.cpp
@@ -23,33 +23,48 @@
 
 namespace {
 
-Scale* scatteringAngles(const std::string& label, size_t n, double angle_min, double angle_max)
+//! Returns true scattering angles for given nominal scale.
+//! The nominal scale is an equidistant partition of the interval between true minimum and
+//! maximum scattering angle. It is used for the graphical representation of detector pixels.
+//! The true scattering angle is used for the computation of scattering towards a detector pixel.
+Scale* scatteringAngles(const Scale& in)
 {
+    const size_t n = in.size();
     ASSERT(n > 0);
-    const double p0 = tan(angle_min);
-    const double dp = (tan(angle_max) - tan(angle_min)) / n;
+    const double p0 = tan(in.min());
+    const double dp = (tan(in.max()) - tan(in.min())) / n;
     std::vector<double> limits;
     limits.reserve(2 * n);
-    limits.push_back(angle_min);
+    limits.push_back(in.min());
     for (size_t i = 1; i < n; ++i) {
         limits.push_back(atan(p0 + i * dp));
         limits.push_back(atan(p0 + i * dp));
     }
-    limits.push_back(angle_max);
-    return newGenericScale(label, limits);
+    limits.push_back(in.max());
+    return newGenericScale(in.axisLabel(), limits);
 }
 
 } // namespace
 
 
+Detector2D::Detector2D(Frame* frame)
+    : IDetector(frame)
+    , m_scattering_phi(::scatteringAngles(frame->xAxis()))
+    , m_scattering_alpha(::scatteringAngles(frame->yAxis()))
+{
+}
+
 Detector2D::Detector2D(size_t n_phi, double phi_min, double phi_max, size_t n_alpha,
                        double alpha_min, double alpha_max)
-    : IDetector(new Frame(::scatteringAngles("phi_f (rad)", n_phi, phi_min, phi_max),
-                          ::scatteringAngles("alpha_f (rad)", n_alpha, alpha_min, alpha_max)))
+    : Detector2D(new Frame(newEquiDivision("phi_f (rad)", n_phi, phi_min, phi_max),
+                           newEquiDivision("alpha_f (rad)", n_alpha, alpha_min, alpha_max)))
 {
 }
 
-Detector2D::Detector2D(const Detector2D& other) = default;
+Detector2D::Detector2D(const Detector2D& other)
+    : Detector2D(other.frame().clone())
+{
+}
 
 Detector2D* Detector2D::clone() const
 {
@@ -58,13 +73,11 @@ Detector2D* Detector2D::clone() const
 
 IPixel* Detector2D::createPixel(size_t index) const
 {
-    const Scale& phi_axis = axis(0);
-    const Scale& alpha_axis = axis(1);
     const size_t phi_index = axisBinIndex(index, 0);
     const size_t alpha_index = axisBinIndex(index, 1);
 
-    const Bin1D alpha_bin = alpha_axis.bin(alpha_index);
-    const Bin1D phi_bin = phi_axis.bin(phi_index);
+    const Bin1D alpha_bin = m_scattering_alpha->bin(alpha_index);
+    const Bin1D phi_bin = m_scattering_phi->bin(phi_index);
     return new SphericalPixel(alpha_bin, phi_bin);
 }
 
@@ -72,9 +85,8 @@ size_t Detector2D::indexOfSpecular(const Beam& beam) const
 {
     double alpha = beam.alpha_i();
     double phi = beam.phi_i();
-    const Scale& phi_axis = axis(0);
-    const Scale& alpha_axis = axis(1);
-    if (phi_axis.rangeComprises(phi) && alpha_axis.rangeComprises(alpha))
-        return getGlobalIndex(phi_axis.closestIndex(phi), alpha_axis.closestIndex(alpha));
+    if (m_scattering_phi->rangeComprises(phi) && m_scattering_alpha->rangeComprises(alpha))
+        return getGlobalIndex(m_scattering_phi->closestIndex(phi),
+                              m_scattering_alpha->closestIndex(alpha));
     return totalSize();
 }
diff --git a/Device/Detector/Detector2D.h b/Device/Detector/Detector2D.h
index a7d07272699a3e82490c3cfd6b99ba15e87bb5f4..f7ecec2b93f362b443cf29d8e5612749e5234b2f 100644
--- a/Device/Detector/Detector2D.h
+++ b/Device/Detector/Detector2D.h
@@ -40,6 +40,12 @@ public:
     //! If no pixel contains this specular wavevector, the number of pixels is
     //! returned. This corresponds to an overflow index.
     size_t indexOfSpecular(const Beam& beam) const override;
+
+private:
+    Detector2D(Frame* frame);
+
+    std::unique_ptr<Scale> m_scattering_phi;
+    std::unique_ptr<Scale> m_scattering_alpha;
 };
 
 #endif // BORNAGAIN_DEVICE_DETECTOR_DETECTOR2D_H