diff --git a/toonz/sources/include/tools/assistant.h b/toonz/sources/include/tools/assistant.h
index c11649c..622d4a7 100644
--- a/toonz/sources/include/tools/assistant.h
+++ b/toonz/sources/include/tools/assistant.h
@@ -198,6 +198,13 @@ public:
 
 class DVAPI TAssistantBase : public TMetaObjectHandler {
   Q_DECLARE_TR_FUNCTIONS(TAssistantBase)
+public:
+  enum {
+    DRAW_ERROR = 1,
+  };
+  
+  static unsigned int drawFlags;
+  
 protected:
   const TStringId m_idEnabled;
   const TStringId m_idPoints;
diff --git a/toonz/sources/tnztools/assistant.cpp b/toonz/sources/tnztools/assistant.cpp
index 002d85f..d82789f 100644
--- a/toonz/sources/tnztools/assistant.cpp
+++ b/toonz/sources/tnztools/assistant.cpp
@@ -25,6 +25,10 @@ const double line_width_scale = 1.5;
 const double line_width_scale = 1.0;
 #endif
 
+
+unsigned int TAssistantBase::drawFlags = 0;
+
+
 //************************************************************************
 //    TGuideline implementation
 //************************************************************************
@@ -421,6 +425,8 @@ void
 TAssistantBase::drawSegment(const TPointD &p0, const TPointD &p1, double pixelSize, double alpha) const {
   double colorBlack[4] = { 0.0, 0.0, 0.0, alpha };
   double colorWhite[4] = { 1.0, 1.0, 1.0, alpha };
+  
+  if (drawFlags & DRAW_ERROR) colorBlack[0] = 1;
 
   glPushAttrib(GL_ALL_ATTRIB_BITS);
   tglEnableBlending();
@@ -629,7 +635,7 @@ TAssistantBase::drawIndex(const TPointD &p, int index, bool selected, double pix
 //---------------------------------------------------------------------------------------------------
 
 void
-TAssistantBase::draw(TToolViewer *viewer, bool enabled) const
+TAssistantBase::draw(TToolViewer*, bool) const
   { }
 
 //---------------------------------------------------------------------------------------------------
diff --git a/toonz/sources/tnztools/assistants/replicatoraffine.cpp b/toonz/sources/tnztools/assistants/replicatoraffine.cpp
index c9d8763..e5e06f1 100644
--- a/toonz/sources/tnztools/assistants/replicatoraffine.cpp
+++ b/toonz/sources/tnztools/assistants/replicatoraffine.cpp
@@ -129,8 +129,21 @@ protected:
     return t1*t0.inv();
   }
   
+  
+  bool isMirror() const {
+    TPointD da0 = m_a0.position - m_center0.position;
+    TPointD db0 = m_b0.position - m_center0.position;
+    TPointD pa0(-da0.y, da0.x);
 
-  void onFixPoints() override {
+    TPointD da1 = m_a1.position - m_center1.position;
+    TPointD db1 = m_b1.position - m_center1.position;
+    TPointD pa1(-da1.y, da0.x);
+    
+    return (pa0*db0 < 0) != (pa1*db1 < 0);
+  }
+  
+
+  void doFixPoints(int mirror) {
     TPointD &c0 = m_center0.position;
     TPointD &a0 = m_a0.position;
     TPointD &b0 = m_b0.position;
@@ -179,18 +192,28 @@ protected:
       double y = (b0 - c0)*pa0;
         
       TPointD da1 = a1 - c1;
+      TPointD db1 = b1 - c1;
       TPointD pa1(-da1.y, da1.x);
+      if (mirror) y *= mirror; else      
+        if ((pa1*db1 < 0) != (y < 0)) y = -y;
+      
       TPointD p = da1*x + pa1*y;
       double l = norm2(p);
       if (l > TConsts::epsilon*TConsts::epsilon)
-        b1 = p*sqrt(tdistance2(b1, c1)/l) + c1;
+        b1 = p*sqrt(norm2(db1)/l) + c1;
     }
   }
+
+  
+  void onFixPoints() override {
+    doFixPoints(0);
+  }
   
   
   void onMovePoint(TAssistantPoint &point, const TPointD &position) override {
     TPointD pc0 = m_center0.position;
     TPointD pc1 = m_center1.position;
+    int mirror = &point == &m_b1 ? 0 : (isMirror() ? -1 : 1);
     point.position = position;
     if (&point == &m_center0) {
       TPointD d = m_center0.position - pc0;
@@ -205,7 +228,7 @@ protected:
       m_a1.position += d;
       m_b1.position += d;
     }
-    onFixPoints();
+    doFixPoints(mirror);
   }
   
   
diff --git a/toonz/sources/tnztools/assistants/replicatorgrid.cpp b/toonz/sources/tnztools/assistants/replicatorgrid.cpp
index 00e1cef..7e731fb 100644
--- a/toonz/sources/tnztools/assistants/replicatorgrid.cpp
+++ b/toonz/sources/tnztools/assistants/replicatorgrid.cpp
@@ -102,8 +102,10 @@ protected:
 
     
   void onSetDefaults() override {
-    setCountA(4);
-    setCountB(4);
+    setCountA(3);
+    setCountAInv(2);
+    setCountB(2);
+    setCountBInv(1);
     TReplicator::onSetDefaults();
   }
 
@@ -129,13 +131,13 @@ protected:
       b = TPointD(0, b.y < c.y ? -lb : lb) + c;
     } else
     if (getFixSkew()) {
-      TPointD da = a - c;
-      double la = norm2(da);
-      if (la > TConsts::epsilon*TConsts::epsilon) {
+      TPointD pa(c.y - a.y, a.x - c.x);
+      double l = norm2(pa);
+      if (l > TConsts::epsilon*TConsts::epsilon) {
         TPointD db = b - c;
-        TPointD pa(-da.y, da.x);
-        double l = pa*db/la;
-        b = pa*l + c;
+        double k = sqrt(norm2(db)/l);
+        if (db*pa < 0) k = -k;
+        b = pa*k + c;
       }
     }
   }
@@ -143,13 +145,14 @@ protected:
   
   void onMovePoint(TAssistantPoint &point, const TPointD &position) override {
     TPointD pc = m_center.position;
+    TPointD pa = m_a.position;
     point.position = position;
     if (&point == &m_center) {
       TPointD d = m_center.position - pc;
       m_a.position += d;
       m_b.position += d;
     } else {
-      onFixPoints();
+      fixPoints();
     }
   }
   
@@ -161,20 +164,7 @@ protected:
         fixPoints();
   }
 
-  
-  static bool makeMirror(TAffine &mirror, const TPointD &c, const TPointD &x) {
-    if (!(norm2(x) > TConsts::epsilon*TConsts::epsilon))
-      return false;
-    TPointD y(-x.y, x.x);
-    TAffine t0( x.x,  y.x, c.x,
-                x.y,  y.y, c.y );
-    TAffine t1( x.x, -y.x, c.x,
-                x.y, -y.y, c.y );
-    mirror = t1*t0.inv();
-    return true;
-  }
-  
-  
+ 
 public:
   int getMultipler() const override {
     return (getCountA() + getCountAInv())
@@ -192,11 +182,24 @@ public:
     TPointD da = toTool*m_a.position - c;
     TPointD db = toTool*m_b.position - c;
     
-    TAffine ma, mb;
+    bool mirrorA = getMirrorA();
+    bool mirrorB = getMirrorB();
+    TAffine t, ma, mb, mc;
+    if (mirrorA || mirrorB) {
+      if (fabs(da*db) > TConsts::epsilon) {
+        t  = TAffine(  da.x,  db.x, c.x,
+                       da.y,  db.y, c.y ).inv();
+        ma = TAffine( -da.x,  db.x, c.x,
+                      -da.y,  db.y, c.y )*t;
+        mb = TAffine(  da.x, -db.x, c.x,
+                       da.y, -db.y, c.y )*t;
+        mc = TAffine( -da.x, -db.x, c.x,
+                      -da.y, -db.y, c.y )*t;
+      } else {
+        mirrorA = mirrorB = false;
+      }
+    }
     
-    bool mirrorA = getMirrorA() && makeMirror(ma, c, da);
-    bool mirrorB = getMirrorB() && makeMirror(ma, c, db);
-
     int a1 = getCountA();
     int b1 = getCountB();
     int a0 = -getCountAInv();
@@ -218,6 +221,10 @@ public:
         modifier->transforms.push_back(TTrackTransform(
           TAffine( mb.a11, mb.a12, mb.a13 + o.x,
                    mb.a21, mb.a22, mb.a23 + o.y ) ));
+      if (mirrorA && mirrorB)
+        modifier->transforms.push_back(TTrackTransform(
+          TAffine( mc.a11, mc.a12, mc.a13 + o.x,
+                   mc.a21, mc.a22, mc.a23 + o.y ) ));
     }
     outModifiers.push_back(modifier);
   }
@@ -253,8 +260,10 @@ public:
         drawSegment(o, o + da*0.2, pixelSize, alpha);
         drawSegment(o, o + db*0.2, pixelSize, alpha);
       }
-      if (mirrorA) drawSegment(o, o - da*0.2, pixelSize, alpha);
-      if (mirrorB) drawSegment(o, o - db*0.2, pixelSize, alpha);
+      if (mirrorA && (ib || ia != 1))
+        drawSegment(o - da*0.2, o, pixelSize, alpha);
+      if (mirrorB && (ia || ib != 1))
+        drawSegment(o - db*0.2, o, pixelSize, alpha);
     }
   }
 };
diff --git a/toonz/sources/tnztools/replicator.cpp b/toonz/sources/tnztools/replicator.cpp
index 59d1a4c..a2a6e04 100644
--- a/toonz/sources/tnztools/replicator.cpp
+++ b/toonz/sources/tnztools/replicator.cpp
@@ -62,6 +62,7 @@ TReplicator::scanReplicators(
   bool markEnabled,
   TImage *skipImage )
 {
+  bool outOfLimit = false;
   long long multiplier = 0;
   
   if (tool)
@@ -109,14 +110,21 @@ TReplicator::scanReplicators(
             if (enabled) {
               int m = replicator->getMultipler();
               if (m <= 0) m = 1;
-              multiplier *= m;
-              if (outModifiers)
-                replicator->getModifiers(imageToTrack, *outModifiers);
-              if (multiplier*m > multiplierLimit)
-                return multiplierLimit;
+              if (multiplier*m > multiplierLimit) {
+                outOfLimit = true;
+              } else {
+                multiplier *= m;
+                if (outModifiers)
+                  replicator->getModifiers(imageToTrack, *outModifiers);
+              }
             }
             
-            if (draw) replicator->draw(viewer, enabled && markEnabled);
+            if (draw) {
+              unsigned int oldFlags = TReplicator::drawFlags;
+              if (enabled && outOfLimit) TReplicator::drawFlags |= TReplicator::DRAW_ERROR;
+              replicator->draw(viewer, enabled && markEnabled);
+              TReplicator::drawFlags = oldFlags;
+            }
           }
 
         if (draw) glPopMatrix();