diff --git a/scripts/Draw/Polyline/DrawPolyline/DrawPolyline.js b/scripts/Draw/Polyline/DrawPolyline/DrawPolyline.js
index fe6e870..429f693 100644
--- a/scripts/Draw/Polyline/DrawPolyline/DrawPolyline.js
+++ b/scripts/Draw/Polyline/DrawPolyline/DrawPolyline.js
@@ -38,6 +38,12 @@ function DrawPolyline(guiAction) {
     this.segment = undefined;
     this.redoList = [];
     this.sweep = 0.0;
+    this.arcCenter = undefined;
+    this.arcPoint = undefined;
+    this.arcEndpoint = undefined;
+    this.selectArc = undefined;
+    this.mode = undefined;
+    this.reversed = false;
 
     this.setUiOptions("DrawPolyline.ui");
 }
@@ -46,13 +52,23 @@ DrawPolyline.prototype = new Polyline();
 
 DrawPolyline.State = {
     SettingFirstVertex : 0,
-    SettingNextVertex : 1
+    SettingNextVertex : 1,
+    SettingArcCenter : 2,
+    SettingArcPoint : 3,
+    SettingArcEndpoint : 4
 };
 
 DrawPolyline.prototype.beginEvent = function() {
     Polyline.prototype.beginEvent.call(this);
+    this.uncheckArcSegment();
 
     this.setState(DrawPolyline.State.SettingFirstVertex);
+    if (this.arcSegment === true) {
+        this.slotModeChanged(this.mode);
+    } else {
+        this.enableDisable("All", false);
+    }
+
     this.updateButtonStates();
 };
 
@@ -71,17 +87,42 @@ DrawPolyline.prototype.initState = function(state) {
         this.setLeftMouseTip(trFirstVertex);
         this.setRightMouseTip(EAction.trCancel);
         this.segment = undefined;
-        EAction.showSnapTools();
         this.redoList = [];
+        EAction.showSnapTools();
         break;
     case DrawPolyline.State.SettingNextVertex:
-        this.getDocumentInterface().setClickMode(RAction.PickCoordinate);
-        var trNextVertex = qsTr("Next vertex");
+        var trNextVertex;
+        if (this.mode === 3 && this.arcSegment === true) {
+            trNextVertex = qsTr("Select arc");
+        } else {
+            trNextVertex = qsTr("Next vertex");
+        }
         this.setCommandPrompt(trNextVertex);
         this.setLeftMouseTip(trNextVertex);
         this.setRightMouseTip(qsTr("Done"));
         EAction.showSnapTools();
         break;
+    case DrawPolyline.State.SettingArcCenter:
+        var trArcCenter = qsTr("Center point");
+        this.setCommandPrompt(trArcCenter);
+        this.setLeftMouseTip(trArcCenter);
+        this.setRightMouseTip(qsTr("Done"));
+        EAction.showSnapTools();
+        break;
+    case DrawPolyline.State.SettingArcPoint:
+        var trArcPoint = qsTr("Point on arc");
+        this.setCommandPrompt(trArcPoint);
+        this.setLeftMouseTip(trArcPoint);
+        this.setRightMouseTip(qsTr("Done"));
+        EAction.showSnapTools();
+        break;
+    case DrawPolyline.State.SettingArcEndpoint:
+        var trArcEndPoint = qsTr("End point of arc");
+        this.setCommandPrompt(trArcEndPoint);
+        this.setLeftMouseTip(trArcEndPoint);
+        this.setRightMouseTip(qsTr("Done"));
+        EAction.showSnapTools();
+        break;
     }
 };
 
@@ -93,7 +134,6 @@ DrawPolyline.prototype.escapeEvent = function() {
     case DrawPolyline.State.SettingFirstVertex:
         EAction.prototype.escapeEvent.call(this);
         break;
-
     case DrawPolyline.State.SettingNextVertex:
         if (!isNull(this.polylineEntity)) {
             // remove polyline with one or zero vertices:
@@ -102,9 +142,27 @@ DrawPolyline.prototype.escapeEvent = function() {
                 this.applyOperation(op);
             }
         }
-
         this.setState(DrawPolyline.State.SettingFirstVertex);
         this.polylineEntity = undefined;
+        this.uncheckArcSegment();
+        this.updateButtonStates();
+        break;
+    case DrawPolyline.State.SettingArcCenter:
+        this.arcCenter = undefined;
+        this.uncheckArcSegment();
+        this.setState(DrawPolyline.State.SettingNextVertex);
+        this.updateButtonStates();
+        break;
+    case DrawPolyline.State.SettingArcPoint:
+        this.arcPoint = undefined;
+        this.uncheckArcSegment();
+        this.setState(DrawPolyline.State.SettingNextVertex);
+        this.updateButtonStates();
+        break;
+    case DrawPolyline.State.SettingArcEndpoint:
+        this.arcEndpoint = undefined;
+        this.uncheckArcSegment();
+        this.setState(DrawPolyline.State.SettingNextVertex);
         this.updateButtonStates();
         break;
     }
@@ -193,38 +251,9 @@ DrawPolyline.prototype.pickCoordinate = function(event, preview) {
                     }
                 }
 
-                this.segment = RArc.createTangential(
-                        appendPoint,
-                        point,
-                        dir,
-                        this.radius);
-
-                // handle sweep here
-                // change end angle
-                // if sweep equals zero then do nothing
-                if (this.sweep < 0.0 || this.sweep > 360.0) {
-                    // print error message
-                    this.sweep = 0.0;
-                }
-                if (this.sweep !== 0.0) {
-                    var curSweep = this.segment.getSweep();
-                    if (curSweep !== this.sweep) {
-                        var startAngle = RMath.rad2deg(this.segment.getStartAngle());
-                        var reversed = this.segment.isReversed();
-                        if (reversed) {
-                            var endAngle = startAngle - this.sweep;
-                            if (endAngle < 0.0) {
-                                endAngle = endAngle + 360.0;
-                            }
-                        } else {
-                            endAngle = startAngle + this.sweep;
-                            if (endAngle > 360.0) {
-                                endAngle = endAngle - 360.0;
-                            }
-                        }
-                        this.segment.setEndAngle(RMath.deg2rad(endAngle));
-                    }
-                }
+                this.doArc(appendPoint, point, dir);
+                this.doSweep();
+
                 vertex = this.segment.getEndPoint();
 
                 if (this.prepend) {
@@ -268,6 +297,27 @@ DrawPolyline.prototype.pickCoordinate = function(event, preview) {
             }
         }
         break;
+    case DrawPolyline.State.SettingArcCenter:
+        if (!preview) {
+            this.arcCenter = event.getModelPosition();
+            di.setRelativeZero(this.arcCenter);
+            this.setState(DrawPolyline.State.SettingNextVertex);
+        }
+        break;
+    case DrawPolyline.State.SettingArcPoint:
+        if (!preview) {
+            this.arcPoint = event.getModelPosition();
+            di.setRelativeZero(this.arcPoint);
+            this.setState(DrawPolyline.State.SettingNextVertex);
+        }
+        break;
+    case DrawPolyline.State.SettingArcEndpoint:
+        if (!preview) {
+            this.arcEndpoint = event.getModelPosition();
+            di.setRelativeZero(this.arcEndpoint);
+            this.setState(DrawPolyline.State.SettingNextVertex);
+        }
+        break;
     }
 
     if (!preview) {
@@ -411,6 +461,142 @@ DrawPolyline.prototype.slotRedo = function() {
  */
 DrawPolyline.prototype.slotArcSegmentChanged = function(value) {
     this.arcSegment = value;
+    var numberOfVertices = 0;
+    if (!isNull(this.polylineEntity)) {
+        numberOfVertices = this.polylineEntity.countVertices();
+    } else {
+        numberOfVertices = 0;
+    }
+    if (this.arcSegment === true) {
+        this.slotModeChanged(this.mode);
+        switch(this.mode) {
+        case 0:
+            if (numberOfVertices > 0) {
+                this.setState(DrawPolyline.State.SettingNextVertex);
+            } else {
+                this.setState(DrawPolyline.State.SettingFirstVertex);
+            }
+            break;
+        case 1:
+            this.setState(DrawPolyline.State.SettingArcCenter);
+            break;
+        case 2:
+            this.setState(DrawPolyline.State.SettingArcPoint);
+            break;
+        }
+    } else {
+        this.enableDisable("All", false);
+        if (numberOfVertices > 0) {
+            this.setState(DrawPolyline.State.SettingNextVertex);
+        } else {
+            this.setState(DrawPolyline.State.SettingFirstVertex);
+        }
+    }
+};
+
+/**
+ * Called when user changes Mode
+ */
+DrawPolyline.prototype.slotModeChanged = function(value) {
+    this.mode = value;
+    var numberOfVertices = 0;
+    if (!isNull(this.polylineEntity)) {
+        numberOfVertices = this.polylineEntity.countVertices();
+    } else {
+        numberOfVertices = 0;
+    }
+
+    switch(value) {
+    case 0:                             //tangential
+        // disable direction
+        this.enableDisable("Direction", false);
+
+        // enable radius and sweep
+        this.enableDisable("Radius", true);
+        this.enableDisable("Sweep", true);
+
+        if (numberOfVertices > 0) {
+            this.setState(DrawPolyline.State.SettingNextVertex);
+        } else {
+            this.setState(DrawPolyline.State.SettingFirstVertex);
+        }
+        break;
+     case 1:                            // Center
+         // disable radius
+         this.enableDisable("Radius", false);
+
+         // enable sweep and direction
+         this.enableDisable("Direction", true);
+         this.enableDisable("Sweep", true);
+
+         this.setState(DrawPolyline.State.SettingArcCenter);
+         break;
+     case 2:                            // Second Pt
+         // disable radius and direction
+         this.enableDisable("Radius", false);
+         this.enableDisable("Direction", false);
+
+         // enable sweep
+         this.enableDisable("Sweep", true);
+
+         this.setState(DrawPolyline.State.SettingArcPoint);
+         break;
+     case 3:                            // End, Radius
+         // enable all options
+         this.enableDisable("Radius", true);
+         this.enableDisable("Sweep", true);
+         this.enableDisable("Direction", true);
+
+         this.setState(DrawPolyline.State.SettingArcEndpoint);
+         break;
+     case 4:                            // End, Sweep
+         // disable radius
+         this.enableDisable("Radius", false);
+
+         // enable sweep and direction
+         this.enableDisable("Sweep", true);
+         this.enableDisable("Direction", true);
+
+         this.setState(DrawPolyline.State.SettingNextVertex);
+         break;
+    }
+};
+
+DrawPolyline.prototype.enableDisable = function(objName, value) {
+    var w;
+
+    if (objName === "Radius") {
+        w = objectFromPath("MainWindow::Options::RadiusLabel");
+        w.enabled = value;
+        w = objectFromPath("MainWindow::Options::Radius");
+        w.enabled = value;
+    }
+    if (objName === "Sweep") {
+        w = objectFromPath("MainWindow::Options::SweepLabel");
+        w.enabled = value;
+        w = objectFromPath("MainWindow::Options::Sweep");
+        w.enabled = value;
+    }
+    if (objName === "Direction") {
+        w = objectFromPath("MainWindow::Options::Counterclockwise");
+        w.enabled = value;
+        w = objectFromPath("MainWindow::Options::Clockwise");
+        w.enabled = value;
+    }
+    if (objName === "All") {
+        w = objectFromPath("MainWindow::Options::RadiusLabel");
+        w.enabled = value;
+        w = objectFromPath("MainWindow::Options::Radius");
+        w.enabled = value;
+        w = objectFromPath("MainWindow::Options::SweepLabel");
+        w.enabled = value;
+        w = objectFromPath("MainWindow::Options::Sweep");
+        w.enabled = value;
+        w = objectFromPath("MainWindow::Options::Counterclockwise");
+        w.enabled = value;
+        w = objectFromPath("MainWindow::Options::Clockwise");
+        w.enabled = value;
+    }
 };
 
 /**
@@ -428,14 +614,26 @@ DrawPolyline.prototype.slotSweepChanged = function(value) {
 };
 
 /**
+  * Called when the user changes direction
+  */
+DrawPolyline.prototype.slotDirectionChanged = function(button) {
+    if (button.objectName ==="Clockwise") {
+        this.reversed = true;
+    }
+    else {
+        this.reversed = false;
+    }
+};
+
+/**
  * Called internally to automatically uncheck the 'Arc segment' check box.
  */
 DrawPolyline.prototype.uncheckArcSegment = function() {
-    var w = objectFromPath("MainWindow::Options::ArcSegment");
+    var optionsToolBar = EAction.getOptionsToolBar();
+    w = optionsToolBar.findChild("ArcSegment");
     w.checked = false;
 };
 
-
 /**
  * Updates the state (enabled / disabled) of the undo and the close buttons
  * depending on the current progress.
@@ -450,18 +648,16 @@ DrawPolyline.prototype.updateButtonStates = function() {
     var optionsToolBar = EAction.getOptionsToolBar();
     w = optionsToolBar.findChild("Close");
     if (!isNull(this.polylineEntity)) {
-        w.enabled = (this.polylineEntity.countVertices() >= 3) ? true : false;
-    }
-    else {
-        w.enabled = false;
+      w.enabled = (this.polylineEntity.countVertices() >= 3) ? true : false;
+    } else {
+      w.enabled = false;
     }
 
     w = optionsToolBar.findChild("Undo");
     if (!isNull(this.polylineEntity)) {
-        w.enabled = (this.polylineEntity.countVertices() >= 2) ? true : false;
-    }
-    else {
-        w.enabled = false;
+      w.enabled = (this.polylineEntity.countVertices() >= 2) ? true : false;
+    } else {
+      w.enabled = false;
     }
 
     w = optionsToolBar.findChild("Redo");
@@ -521,3 +717,174 @@ DrawPolyline.prototype.commandEvent = function(event) {
         return;
     }
 };
+
+/**
+  * doArc - Create an arc based on mode and assign to global var this.segment
+  */
+DrawPolyline.prototype.doArc = function(point1, point2, direction) {
+    switch(this.mode) {
+    case 0:                 // tangential
+        this.segment = RArc.createTangential(
+                point1,
+                point2,
+                direction,
+                this.radius);
+        break;
+    case 1:                 // centre
+        this.radius = this.arcCenter.getDistanceTo(point1);
+        var angle1 = this.arcCenter.getAngleTo(point1);
+        var angle2 = this.arcCenter.getAngleTo(point2);
+        this.segment = new RArc(
+                this.arcCenter,
+                this.radius,
+                angle1,
+                angle2,
+                this.reversed
+            );
+        break;
+    case 2:                 // second pt
+        this.segment = RArc.createFrom3Points(
+                 point1,
+                 this.arcPoint,
+                 point2);
+        break;
+    case 3:                 // end, radius
+        // End, Radius
+        this.point1 = point1;
+        this.point2 = point2;
+        if (isNull(this.point1) || isNull(this.point2) || !isNumber(this.radius)) {
+            return undefined;
+        }
+
+        if (this.radius <= 0.0 || this.radius > 1.0e6) {
+            if (!preview) {
+                this.error = qsTr("Invalid radius");
+            }
+            return undefined;
+        }
+
+        if (this.point1.equalsFuzzy(this.point2)) {
+            if (!preview) {
+                this.error = qsTr("The two points are identical");
+            }
+            return undefined;
+        }
+
+        var circle1 = new RCircle(this.point1, this.radius);
+        var circle2 = new RCircle(this.arcEndpoint, this.radius);
+
+        var ips = circle1.getIntersectionPoints(circle2, false);
+
+        if (ips.length === 2) {
+            var ipRight, ipLeft;
+            var line = new RLine(this.point1, this.point2);
+            if (line.getSideOfPoint(ips[0]) === RS.RightHand) {
+                ipRight = ips[0];
+                ipLeft = ips[1];
+            }
+            else {
+                ipLeft = ips[0];
+                ipRight = ips[1];
+            }
+
+            if (this.point2.getDistanceTo(ipLeft) < this.point2.getDistanceTo(ipRight)) {
+                this.center = ipLeft;
+            } else {
+                this.center = ipRight;
+            }
+        }
+        else {
+            // center in the middle:
+            var v = new RVector();
+            v.setPolar(this.radius, this.point1.getAngleTo(this.arcEndpoint));
+            this.center = this.point1.operator_add(v);
+        }
+
+        angle1 = this.center.getAngleTo(this.point1);
+        angle2 = this.center.getAngleTo(this.arcEndpoint);
+
+        this.segment = new RArc(this.center, this.radius, angle1, angle2, this.reversed);
+        break;
+    case 4:                 // end, sweep
+        // End, Sweep
+        this.point1 = point1;
+        this.point2 = point2;
+        this.angle = RMath.deg2rad(this.sweep);
+        if (isNull(this.point1) || isNull(this.point2) || isNull(this.angle)) {
+            return undefined;
+        }
+
+        if (this.point1.equalsFuzzy(this.point2)) {
+            if (!preview) {
+                this.error = qsTr("The two points are identical");
+            }
+            return undefined;
+        }
+
+        var angle = this.point1.getAngleTo(this.point2);
+        var angle90 = angle + Math.PI/2;
+        var a1, a2;
+        if (this.reversed===true) {
+            a1 = angle90 + this.angle/2;
+            a2 = angle90 - this.angle/2;
+        }
+        else {
+            a1 = angle90 - this.angle/2;
+            a2 = angle90 + this.angle/2;
+        }
+
+        var v1 = new RVector();
+        v1.setPolar(1.0, a1);
+        var v2 = new RVector();
+        v2.setPolar(1.0, a2);
+
+        var line1 = new RLine(this.point1, this.point1.operator_add(v1));
+        var line2 = new RLine(this.point2, this.point2.operator_add(v2));
+
+        var ips = line1.getIntersectionPoints(line2, false);
+
+        if (ips.length===1) {
+            this.center = ips[0];
+        }
+        else {
+            this.center = RVector.getAverage(this.point1, this.point2);
+        }
+
+        var radius = this.center.getDistanceTo(this.point1);
+        angle1 = this.center.getAngleTo(this.point1);
+        angle2 = this.center.getAngleTo(this.point2);
+
+        this.segment = new RArc(this.center, radius, angle1, angle2, this.reversed);
+        break;
+    }
+};
+
+/**
+  * doSweep - Adjust end angle of arc to change included angle
+  */
+DrawPolyline.prototype.doSweep = function() {
+    // if sweep equals zero then do nothing
+    if (this.sweep < 0.0 || this.sweep > 360.0) {
+        // print error message
+        this.sweep = 0.0;
+    }
+    if (this.sweep !== 0.0) {
+        var curSweep = RMath.rad2deg(this.segment.getSweep());
+        if (curSweep !== this.sweep) {
+            var startAngle = RMath.rad2deg(this.segment.getStartAngle());
+            var reversed = this.segment.isReversed();
+            if (reversed) {
+                var endAngle = startAngle - this.sweep;
+                if (endAngle < 0.0) {
+                    endAngle = endAngle + 360.0;
+                }
+            } else {
+                endAngle = startAngle + this.sweep;
+                if (endAngle > 360.0) {
+                    endAngle = endAngle - 360.0;
+                }
+            }
+            this.segment.setEndAngle(RMath.deg2rad(endAngle));
+        }
+    }
+};
