.NET

Reply
New Member
m.schilder
Posts: 2
Registered: ‎06-12-2013
Message 1 of 4 (480 Views)
Accepted Solution

Prompt user to pick point on circle with given radius

480 Views, 3 Replies
07-25-2013 02:04 AM

Hi!

 

I'm searching for a solution to achieve the following:

 

I need my users to pick a point p, enter a distance r and a direction v. A new point should be created r units away in vectorial direction. Therefore, the new point is located on an imaginary circle with radius r and center p.

 

Currently, the user picks the first point and enters a distance. Then, he has to pick another point (Editor.GetPoint with UseBasePoint = true), I calculate the vector between both points, create a new point (with location = BasePoint.location) and translate it d units in vectorial direction. This works of course, but the problem is, that the user doesn't see directly, where his new point is located, since he may pick a point closer to or farther away then r units.

 

Naively spoken, I want to restrict the line between BasePoint and new point while prompting the user to a fixed length. Is there any way to achieve this? Native calls to ObjectARX-methods would be also okay.

 

Thank you!

 

Hi,

 

Maybe you can use a Jig to show the point durring the prompt for angle.

 

using System;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.GraphicsInterface;
using Autodesk.AutoCAD.Runtime;
[assembly: CommandClass(typeof(JigPointOnCircleSample.CommandMethods))]
namespace JigPointOnCircleSample
{
public class CommandMethods
{
[CommandMethod("Test", CommandFlags.Modal)]
public void Test()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
int pdmode = db.Pdmode;
double pdsize = db.Pdsize;
try
{
db.Pdmode = 3;
db.Pdsize = -3.0;
PromptPointResult ppr = ed.GetPoint("\nCenter: ");
if (ppr.Status != PromptStatus.OK) return;
PromptDistanceOptions pdo = new PromptDistanceOptions("\nRadius: ");
pdo.BasePoint = ppr.Value;
pdo.UseBasePoint = true;
PromptDoubleResult pdr = ed.GetDistance(pdo);
if (pdr.Status != PromptStatus.OK) return;
Point3d center = ppr.Value.TransformBy(ed.CurrentUserCoordinateSystem);
double radius = pdr.Value;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTableRecord btr =
(BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
while (true)
{
using (DBPoint point = new DBPoint())
{
DBPointJig jig = new DBPointJig(point, center, radius);
PromptResult pr = ed.Drag(jig);
if (pr.Status != PromptStatus.OK) break;
btr.AppendEntity(point);
tr.AddNewlyCreatedDBObject(point, true);
db.TransactionManager.QueueForGraphicsFlush();
}
}
tr.Commit();
}
}
catch (System.Exception ex)
{
ed.WriteMessage("\nError: " + ex.Message + ex.StackTrace);
}
finally
{
db.Pdmode = pdmode;
db.Pdsize = pdsize;
ed.Regen();
}
}
}
class DBPointJig : EntityJig
{
private double radius, angle;
private Point3d center;
private DBPoint point;
public DBPointJig(DBPoint point, Point3d center, double radius)
: base(point)
{
this.point = point;
this.center = center;
this.radius = radius;
}
protected override bool Update()
{
point.Position = Polar(center, angle, radius);
return true;
}
protected override SamplerStatus Sampler(JigPrompts prompts)
{
JigPromptAngleOptions opt = new JigPromptAngleOptions("\nAngle: ");
opt.BasePoint = center;
opt.UseBasePoint = true;
opt.Cursor = CursorType.RubberBand;
opt.UserInputControls =
UserInputControls.UseBasePointElevation | UserInputControls.NullResponseAccepted;
PromptDoubleResult pdr = prompts.AcquireAngle(opt);
if (pdr.Status == PromptStatus.Cancel || pdr.Status == PromptStatus.Error)
return SamplerStatus.Cancel;
else if (pdr.Value == angle)
return SamplerStatus.NoChange;
else
{
angle = pdr.Value;
return SamplerStatus.OK;
}
}
private Point3d Polar(Point3d center, double angle, double distance)
{
return new Point3d(
center.X + distance * Math.Cos(this.angle),
center.Y + distance * Math.Sin(this.angle),
center.Z);
}
}
}

 

 

ADN Support Specialist
fenton.webb
Posts: 352
Registered: ‎07-24-2007
Message 2 of 4 (447 Views)

Re: Prompt user to pick point on circle with given radius

07-25-2013 03:05 PM in reply to: m.schilder

I like this sample project http://spiderinnet1.typepad.com/blog/2012/01/autocad-net-entityjig-jig-circle-by-center-and-radius.h...





Fenton Webb

Developer Technical Services

Autodesk Developer Network


*Expert Elite*
_gile
Posts: 2,115
Registered: ‎04-29-2006
Message 3 of 4 (435 Views)

Re : Prompt user to pick point on circle with given radius

07-26-2013 03:59 AM in reply to: m.schilder

Hi,

 

Maybe you can use a Jig to show the point durring the prompt for angle.

 

using System;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.GraphicsInterface;
using Autodesk.AutoCAD.Runtime;

[assembly: CommandClass(typeof(JigPointOnCircleSample.CommandMethods))]

namespace JigPointOnCircleSample
{
    public class CommandMethods
    {
        [CommandMethod("Test", CommandFlags.Modal)]
        public void Test()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            int pdmode = db.Pdmode;
            double pdsize = db.Pdsize;

            try
            {
                db.Pdmode = 3;
                db.Pdsize = -3.0;

                PromptPointResult ppr = ed.GetPoint("\nCenter: ");
                if (ppr.Status != PromptStatus.OK) return;

                PromptDistanceOptions pdo = new PromptDistanceOptions("\nRadius: ");
                pdo.BasePoint = ppr.Value;
                pdo.UseBasePoint = true;
                PromptDoubleResult pdr = ed.GetDistance(pdo);
                if (pdr.Status != PromptStatus.OK) return;

                Point3d center = ppr.Value.TransformBy(ed.CurrentUserCoordinateSystem);
                double radius = pdr.Value;

                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    BlockTableRecord btr =
                        (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                    while (true)
                    {
                        using (DBPoint point = new DBPoint())
                        {
                            DBPointJig jig = new DBPointJig(point, center, radius);
                            PromptResult pr = ed.Drag(jig);
                            if (pr.Status != PromptStatus.OK) break;

                            btr.AppendEntity(point);
                            tr.AddNewlyCreatedDBObject(point, true);
                            db.TransactionManager.QueueForGraphicsFlush();
                        }
                    }
                    tr.Commit();
                }
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage("\nError: " + ex.Message + ex.StackTrace);
            }
            finally
            {
                db.Pdmode = pdmode;
                db.Pdsize = pdsize;
                ed.Regen();
            }
        }
    }

    class DBPointJig : EntityJig
    {
        private double radius, angle;
        private Point3d center;
        private DBPoint point;

        public DBPointJig(DBPoint point, Point3d center, double radius)
            : base(point)
        {
            this.point = point;
            this.center = center;
            this.radius = radius;
        }

        protected override bool Update()
        {
            point.Position = Polar(center, angle, radius);
            return true;
        }

        protected override SamplerStatus Sampler(JigPrompts prompts)
        {
            JigPromptAngleOptions opt = new JigPromptAngleOptions("\nAngle: ");
            opt.BasePoint = center;
            opt.UseBasePoint = true;
            opt.Cursor = CursorType.RubberBand;
            opt.UserInputControls =
                UserInputControls.UseBasePointElevation | UserInputControls.NullResponseAccepted;
            PromptDoubleResult pdr = prompts.AcquireAngle(opt);
            if (pdr.Status == PromptStatus.Cancel || pdr.Status == PromptStatus.Error)
                return SamplerStatus.Cancel;
            else if (pdr.Value == angle)
                return SamplerStatus.NoChange;
            else
            {
                angle = pdr.Value;
                return SamplerStatus.OK;
            }
        }

        private Point3d Polar(Point3d center, double angle, double distance)
        {
            return new Point3d(
                center.X + distance * Math.Cos(this.angle),
                center.Y + distance * Math.Sin(this.angle),
                center.Z);
        }
    }
}

 

 

Gilles Chanteau
New Member
m.schilder
Posts: 2
Registered: ‎06-12-2013
Message 4 of 4 (412 Views)

Re: Prompt user to pick point on circle with given radius

07-29-2013 12:25 AM in reply to: m.schilder

Hi _gine,

 

seems to be the solution, for the moment. Thank you.

 

If anyone is curious how _gine's solution looks like: see the attached screenshot. The 'x' marks a point on an (imaginary) circle with pre-entered center and radius.

 

I have an old C++-code snippet, which (I guess) allows picking a point at specified distance with a fixed-length rubberband. Unfortunately, I'm not able to validate my assumptions, since it's an old, abandoned project which I'm not able to compile. Furthermore, I wasn't able to find any documentation on the used ads_*-functions. Maybe someone is interesed in this.

 

int GetPointAtDistance(ads_point base, double dDistance, ads_point retPoint, int *piKeyCode)
{
	int ret = 0;
	int result;
	struct resbuf ergebnis;
	double angle_old, angle;
	angle_old = 0;
	World2Ucs(base);
	ads_polar(base,0,dDistance,retPoint);
	ads_grdraw(base,retPoint,-1,0);
	do
	{
		result = 0;
		ret = ads_grread(15,&result,&ergebnis);
		if (ret != RTNORM)
		{
			ads_grdraw(base,retPoint,-1,0);
			return ret;
		}
		switch(result)
		{
			case 2:
				if(piKeyCode)
				{
					ads_grdraw(base,retPoint,-1,0);
					*piKeyCode = ergebnis.resval.rint;
					ret = RTKWORD;
				}
				break;
			case 5:
				angle = ads_angle(base,ergebnis.resval.rpoint);
				if (angle != angle_old)
				{
					ads_grdraw(base,retPoint,-1,0);
					ads_polar(base,angle,dDistance,retPoint);
					ads_grdraw(base,retPoint,-1,0);
				}
				angle_old = angle;
				break;
			case 3:
				ads_grdraw(base,retPoint,-1,0);
				angle = ads_angle(base,ergebnis.resval.rpoint);
				ads_polar(base,angle,dDistance,retPoint);
				break;
			case 12:
				ads_grdraw(base,retPoint,-1,0);
				ret = RTCAN;
				break;
		}
	} while(result != 3 && ret == RTNORM);
	return ret;
}

 

Post to the Community

Have questions about Autodesk products? Ask the community.

New Post
Announcements
Are You Going To Be @ AU 2014? Feel free to drop by our AU topic post and share your plans, plug a class that you're teaching, or simply check out who else from the community might be in attendance. Ohh and don't forgot to stop by the Autodesk Help | Learn | Collaborate booths in the Exhibit Hall and meet our community team if you get a chance!