OK, your question does not have anything to do with the first triangle jig. The actual issue you have is when a jig (the circle jig, in your case) starts, you want to moving entity (circle) inside a given boundary, regardless where the moving entity's original position is (inside or outside the target boundary), thus your thought to set the cursor's position inside the boundary when the jig starts.
Again, you should not try to set the cursor position. Instead, you should constrain the ghost image of the moving entity only appears inside the boundary regardless where user moves the mouse cursor to. That is, when the cursor is outside the boundary, you would calculate the moving entity's position inside the boundary, so that its distance to the mouse cursor is shortest. Following code and the video clip shows the concept of doing it. For simplicity, I use a Circle as the constraining boundary. Obviously, since your boundary a rectangle and the moving entity is a circle, in order to dragging the moving circle near the rectangle's corners without letting the circle cross the boundary, you may want to create a boundary in memory for calculating purpose, which should have round corner with the fillet radius equal to the moving circle's. Again, the code is only meant to show the idea.
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.GraphicsInterface;
using System;
namespace AreaIntersectionJig
{
public class AreaConstrainedJig : DrawJig, IDisposable
{
private readonly Document _dwg;
private readonly Database _db;
private readonly Editor _ed;
private Transaction _transaction = null;
private Circle _movingCircle = null;
private Circle _boundary = null;
private Point3d _currPoint;
private Point3d _prevPoint;
public AreaConstrainedJig(Document dwg)
{
_dwg = dwg;
_db = _dwg.Database;
_ed= _dwg.Editor;
_transaction = _db.TransactionManager.StartTransaction();
}
public void Dispose()
{
_transaction.Dispose();
}
public void Drag()
{
if (!SelectWorkObjects(out _movingCircle, out _boundary))
{
_ed.WriteMessage("\n*Cancel*\n");
return;
}
_currPoint = _movingCircle.Center;
_prevPoint = _currPoint;
_movingCircle.Highlight();
var res = _ed.Drag(this);
if (res.Status == PromptStatus.OK)
{
_transaction.Commit();
}
else
{
_transaction.Abort();
}
_movingCircle.Unhighlight();
}
protected override SamplerStatus Sampler(JigPrompts prompts)
{
var opt = new JigPromptPointOptions(
"\nMove selected circle to area within circle boundary:");
var res = prompts.AcquirePoint(opt);
if (res.Status== PromptStatus.OK)
{
_prevPoint= _currPoint;
_currPoint = CalculateMovingCircleCenter(res.Value);
if (_currPoint==_prevPoint)
{
return SamplerStatus.NoChange;
}
else
{
var mt=Matrix3d.Displacement(_prevPoint.GetVectorTo(_currPoint));
_movingCircle.TransformBy(mt);
return SamplerStatus.OK;
}
}
else
{
return SamplerStatus.Cancel;
}
}
protected override bool WorldDraw(WorldDraw draw)
{
return draw.Geometry.Draw(_movingCircle);
}
#region private methods
private bool SelectWorkObjects(out Circle circle, out Circle boundary)
{
circle = null;
boundary = null;
var opts = new PromptEntityOptions("\nSelect circle to move:");
opts.SetRejectMessage("\bInvalid: not a CIRCLE.");
opts.AddAllowedClass(typeof(Circle), true);
var res=_ed.GetEntity(opts);
if (res.Status == PromptStatus.OK)
{
var circleId = res.ObjectId;
while (true)
{
opts = new PromptEntityOptions("\nSelect a circle boundary:");
opts.SetRejectMessage("\nInvalid: not a CIRCLE.");
opts.AddAllowedClass(typeof(Circle), true);
res = _ed.GetEntity(opts);
if (res.Status == PromptStatus.OK)
{
_boundary = (Circle)_transaction.GetObject(res.ObjectId, OpenMode.ForRead);
circle=(Circle)_transaction.GetObject(circleId, OpenMode.ForWrite);
break;
}
else
{
return false;
}
}
}
else
{
return false;
}
return true;
}
private Point3d CalculateMovingCircleCenter(Point3d cursorPoint)
{
if (IsCursorInsideBoundary(cursorPoint))
{
var closestPt = _boundary.GetClosestPointTo(cursorPoint, false);
var distToBoundary = cursorPoint.DistanceTo(closestPt);
if (distToBoundary>=_movingCircle.Radius || closestPt.IsEqualTo(cursorPoint))
{
return cursorPoint;
}
else
{
try
{
Point3d centerPt;
using (var ray = new Ray())
{
ray.BasePoint = cursorPoint;
ray.SecondPoint = cursorPoint;
centerPt = ray.GetPointAtDist(_movingCircle.Radius);
}
return centerPt;
}
catch
{
return _currPoint;
}
}
}
else
{
Point3d centerPt;
var closestPt = _boundary.GetClosestPointTo(cursorPoint, false);
using (var ray = new Ray())
{
ray.BasePoint = cursorPoint;
ray.SecondPoint = closestPt;
var dist = cursorPoint.DistanceTo(closestPt) + _movingCircle.Radius;
centerPt = ray.GetPointAtDist(dist);
}
return centerPt;
}
}
private bool IsCursorInsideBoundary(Point3d cursorPoint)
{
var dist= cursorPoint.DistanceTo(_boundary.Center);
return dist <= _boundary.Radius;
}
#endregion
}
}
To run the jig:
[CommandMethod("DragInside")]
public static void DragEntityInside()
{
var dwg = CadApp.DocumentManager.MdiActiveDocument;
var editor = dwg.Editor;
using (var jig=new AreaConstrainedJig(dwg))
{
jig.Drag();
}
}