尝试在 C# 上使用 AutoCAD class 镜像绘图
Trying to mirror a drawing using the AutoCAD class on C#
目前我有一个使用 AutoCAD 绘制的对象 class 但我可以选择在绘制后对其进行镜像。我不知道该怎么做。
[CommandMethod("DrawTestDoor")]
public void DrawTestDoor()
{
Document acDoc = Application.DocumentManager.MdiActiveDocument;
var ed = acDoc.Editor;
XDDoor s1 = new XDDoor();
PromptKeywordOptions pKeyOpts = new PromptKeywordOptions("");
pKeyOpts.Message = "\nIt is Rated ";
pKeyOpts.Keywords.Add("True");
pKeyOpts.Keywords.Add("False");
pKeyOpts.Keywords.Default = "True";
pKeyOpts.AllowNone = true;
PromptResult pKeyRes = acDoc.Editor.GetKeywords(pKeyOpts);
bool fireRated = Convert.ToBoolean(pKeyRes.StringResult);
var promptResultheight = ed.GetString("\nEnter the Frame height: ");
double height = Convert.ToDouble(promptResultheight.StringResult);
var promptResultwidth = ed.GetString("\nFrame Width: ");
double width = Convert.ToDouble(promptResultwidth.StringResult);
var promptResultFrameDepthChange = ed.GetString("\nEnter the frame depth change ");
double frameDepthChange = Convert.ToDouble(promptResultFrameDepthChange.StringResult);
PromptKeywordOptions pKeyOpts1 = new PromptKeywordOptions("");
pKeyOpts1.Message = "\nDoor Handle Side";
pKeyOpts1.Keywords.Add("Left");
pKeyOpts1.Keywords.Add("Right");
pKeyOpts1.Keywords.Default = "Left";
pKeyOpts1.AllowNone = true;
s1.DrawSingleXDDoor(height, width, fireRated, frameDepthChange);
Matrix2d md = new Matrix2d();
md.Translation.Mirror()
}
这条 md.Translation.Mirror()
是我认为需要更改的行。我已经尝试了多种方法来制作镜像,但我一直回到这个问题,因为我不知道 s1
对象被原样保存的是什么。也许认为它需要转换为实体?
public void DrawSingleXDDoor(double height, double width, bool fireRated, double frameDepthChange)
{
DrawLid("lid", leafHeight, lidWidth);
}
public void DrawLid(string type, double height, double width)
{
DrawShapes d1 = new DrawShapes();
DrawComponents xd = new DrawComponents();
d1.DrawRectangle(0, 0, height, width);
}
public void DrawRectangle(double startx, double starty, double recHeight, double recWidth)
{
double height = recHeight;
double width = recWidth;
//Get the drawing document and the dataabses object
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
using (Transaction trans = db.TransactionManager.StartTransaction())
{
try
{
BlockTable bt;
bt = trans.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord btr;
btr = trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
Polyline p1 = new Polyline();
p1.AddVertexAt(0, new Point2d(startx + 0, starty + 0), 0, 0, 0);
p1.AddVertexAt(0, new Point2d(startx + 0, starty + height), 0, 0, 0);
p1.AddVertexAt(0, new Point2d(startx + width, starty + height), 0, 0, 0);
p1.AddVertexAt(0, new Point2d(startx + width, starty + 0), 0, 0, 0);
p1.AddVertexAt(0, new Point2d(startx + 0, starty + 0), 0, 0, 0);
p1.SetDatabaseDefaults();
btr.AppendEntity(p1);
trans.AddNewlyCreatedDBObject(p1, true);
trans.Commit();
}
catch (System.Exception ex)
{
doc.Editor.WriteMessage("Error encountered: " + ex.Message);
trans.Abort();
}
}
}
此示例取自 AutoCAD 2017 .Net SDK。
您似乎错过了在变换上设置镜像点并将镜像副本插入 BlockTable
。下面的代码应该在添加新的 p1 (polyline)
后直接执行。我从 here 获得了这个代码示例。试一试,让我知道。干杯!
// Define the mirror line
Point3d acPtFrom = new Point3d(0, 4.25, 0);
Point3d acPtTo = new Point3d(4, 4.25, 0);
Line3d acLine3d = new Line3d(acPtFrom, acPtTo);
// Mirror the polyline across the X axis
acPolyMirCopy.TransformBy(Matrix3d.Mirroring(acLine3d));
// Add the new object to the block table record and the transaction
acBlkTblRec.AppendEntity(acPolyMirCopy);
acTrans.AddNewlyCreatedDBObject(acPolyMirCopy, true);
直到现在我才弄明白这一点。许多试验和错误。我会尽最大努力通过示例提供尽可能多的代码
arrays.cs
public void PopulateWithOldArray(List<double> newArray, List<double> oldArray, bool negate)
{
//if there are any previous version of the new array we want them to be cleared so that the called old array will not be affected
newArray.Clear();
if (negate == true)
{
for (int i = 0; i < oldArray.Count; i++)
{
newArray.Add(-oldArray[i]);
}
}
else
{
for (int i = 0; i < oldArray.Count; i++)
{
newArray.Add(oldArray[i]);
}
}
}//end PopulateWithOldArray
public void MirrorXaxis(double startx, double starty, List<double> x, List<double> y, List<double> angle)
{
List<double> changedx = new List<double> { };
List<double> changedangle = new List<double> { };
PopulateWithOldArray(changedx, x, true);
PopulateWithOldArray(changedangle, angle, true);
DrawShapes ds = new DrawShapes();
for (int i = 0; i < angle.Count; i++)
{
ds.DrawPolyLine(changedx[i] + startx, y[i] + starty, changedx[i + 1] + startx, y[i + 1] + starty, changedangle[i]);
}//end for
}//end mirror
drawshapes.cs
using System;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;
namespace doorsetsDraw
{
class DrawShapes
{
public void DrawPolyLine(double startx, double starty, double endx, double endy, double endBulgeAngle)
{
//Get the drawing document and the dataabses object
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
//create the transaction object inside the using block
using (Transaction trans = db.TransactionManager.StartTransaction())
{
try
{
//get the blocktable object
//doc.Editor.WriteMessage("Drawing a 2d Polyline!"); //extra option to last editor
BlockTable bt;
bt = trans.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord btr;
btr = trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; //draw into model space
//specify the polyline's coordinates
Polyline p1 = new Polyline();
p1.AddVertexAt(0, new Point2d(startx, starty), 0, 0, 0);
p1.AddVertexAt(0, new Point2d(endx, endy), BulgeEquationTan(endBulgeAngle), 0, 0);
p1.SetDatabaseDefaults();
btr.AppendEntity(p1);
trans.AddNewlyCreatedDBObject(p1, true);
trans.Commit();
}
catch (System.Exception ex)
{
doc.Editor.WriteMessage("Error encountered: " + ex.Message);
trans.Abort();
//abort to roll out of excpetion for unreferenced object
}//end catch
}//end using
}//end drawpolylineElip
public double BulgeEquationTan(double angleD)
{
double tanV = ConvertToRadians(angleD) / 4;
double tanA = Math.Tan(tanV);
return tanA;
}//end BulgeEquationTan
public double ConvertToRadians(double angle)
{
return (Math.PI / 180) * angle;
}//end ConvertToRadians
}
}
目前我有一个使用 AutoCAD 绘制的对象 class 但我可以选择在绘制后对其进行镜像。我不知道该怎么做。
[CommandMethod("DrawTestDoor")]
public void DrawTestDoor()
{
Document acDoc = Application.DocumentManager.MdiActiveDocument;
var ed = acDoc.Editor;
XDDoor s1 = new XDDoor();
PromptKeywordOptions pKeyOpts = new PromptKeywordOptions("");
pKeyOpts.Message = "\nIt is Rated ";
pKeyOpts.Keywords.Add("True");
pKeyOpts.Keywords.Add("False");
pKeyOpts.Keywords.Default = "True";
pKeyOpts.AllowNone = true;
PromptResult pKeyRes = acDoc.Editor.GetKeywords(pKeyOpts);
bool fireRated = Convert.ToBoolean(pKeyRes.StringResult);
var promptResultheight = ed.GetString("\nEnter the Frame height: ");
double height = Convert.ToDouble(promptResultheight.StringResult);
var promptResultwidth = ed.GetString("\nFrame Width: ");
double width = Convert.ToDouble(promptResultwidth.StringResult);
var promptResultFrameDepthChange = ed.GetString("\nEnter the frame depth change ");
double frameDepthChange = Convert.ToDouble(promptResultFrameDepthChange.StringResult);
PromptKeywordOptions pKeyOpts1 = new PromptKeywordOptions("");
pKeyOpts1.Message = "\nDoor Handle Side";
pKeyOpts1.Keywords.Add("Left");
pKeyOpts1.Keywords.Add("Right");
pKeyOpts1.Keywords.Default = "Left";
pKeyOpts1.AllowNone = true;
s1.DrawSingleXDDoor(height, width, fireRated, frameDepthChange);
Matrix2d md = new Matrix2d();
md.Translation.Mirror()
}
这条 md.Translation.Mirror()
是我认为需要更改的行。我已经尝试了多种方法来制作镜像,但我一直回到这个问题,因为我不知道 s1
对象被原样保存的是什么。也许认为它需要转换为实体?
public void DrawSingleXDDoor(double height, double width, bool fireRated, double frameDepthChange)
{
DrawLid("lid", leafHeight, lidWidth);
}
public void DrawLid(string type, double height, double width)
{
DrawShapes d1 = new DrawShapes();
DrawComponents xd = new DrawComponents();
d1.DrawRectangle(0, 0, height, width);
}
public void DrawRectangle(double startx, double starty, double recHeight, double recWidth)
{
double height = recHeight;
double width = recWidth;
//Get the drawing document and the dataabses object
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
using (Transaction trans = db.TransactionManager.StartTransaction())
{
try
{
BlockTable bt;
bt = trans.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord btr;
btr = trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
Polyline p1 = new Polyline();
p1.AddVertexAt(0, new Point2d(startx + 0, starty + 0), 0, 0, 0);
p1.AddVertexAt(0, new Point2d(startx + 0, starty + height), 0, 0, 0);
p1.AddVertexAt(0, new Point2d(startx + width, starty + height), 0, 0, 0);
p1.AddVertexAt(0, new Point2d(startx + width, starty + 0), 0, 0, 0);
p1.AddVertexAt(0, new Point2d(startx + 0, starty + 0), 0, 0, 0);
p1.SetDatabaseDefaults();
btr.AppendEntity(p1);
trans.AddNewlyCreatedDBObject(p1, true);
trans.Commit();
}
catch (System.Exception ex)
{
doc.Editor.WriteMessage("Error encountered: " + ex.Message);
trans.Abort();
}
}
}
此示例取自 AutoCAD 2017 .Net SDK。
您似乎错过了在变换上设置镜像点并将镜像副本插入 BlockTable
。下面的代码应该在添加新的 p1 (polyline)
后直接执行。我从 here 获得了这个代码示例。试一试,让我知道。干杯!
// Define the mirror line
Point3d acPtFrom = new Point3d(0, 4.25, 0);
Point3d acPtTo = new Point3d(4, 4.25, 0);
Line3d acLine3d = new Line3d(acPtFrom, acPtTo);
// Mirror the polyline across the X axis
acPolyMirCopy.TransformBy(Matrix3d.Mirroring(acLine3d));
// Add the new object to the block table record and the transaction
acBlkTblRec.AppendEntity(acPolyMirCopy);
acTrans.AddNewlyCreatedDBObject(acPolyMirCopy, true);
直到现在我才弄明白这一点。许多试验和错误。我会尽最大努力通过示例提供尽可能多的代码
arrays.cs
public void PopulateWithOldArray(List<double> newArray, List<double> oldArray, bool negate)
{
//if there are any previous version of the new array we want them to be cleared so that the called old array will not be affected
newArray.Clear();
if (negate == true)
{
for (int i = 0; i < oldArray.Count; i++)
{
newArray.Add(-oldArray[i]);
}
}
else
{
for (int i = 0; i < oldArray.Count; i++)
{
newArray.Add(oldArray[i]);
}
}
}//end PopulateWithOldArray
public void MirrorXaxis(double startx, double starty, List<double> x, List<double> y, List<double> angle)
{
List<double> changedx = new List<double> { };
List<double> changedangle = new List<double> { };
PopulateWithOldArray(changedx, x, true);
PopulateWithOldArray(changedangle, angle, true);
DrawShapes ds = new DrawShapes();
for (int i = 0; i < angle.Count; i++)
{
ds.DrawPolyLine(changedx[i] + startx, y[i] + starty, changedx[i + 1] + startx, y[i + 1] + starty, changedangle[i]);
}//end for
}//end mirror
drawshapes.cs
using System;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;
namespace doorsetsDraw
{
class DrawShapes
{
public void DrawPolyLine(double startx, double starty, double endx, double endy, double endBulgeAngle)
{
//Get the drawing document and the dataabses object
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
//create the transaction object inside the using block
using (Transaction trans = db.TransactionManager.StartTransaction())
{
try
{
//get the blocktable object
//doc.Editor.WriteMessage("Drawing a 2d Polyline!"); //extra option to last editor
BlockTable bt;
bt = trans.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord btr;
btr = trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; //draw into model space
//specify the polyline's coordinates
Polyline p1 = new Polyline();
p1.AddVertexAt(0, new Point2d(startx, starty), 0, 0, 0);
p1.AddVertexAt(0, new Point2d(endx, endy), BulgeEquationTan(endBulgeAngle), 0, 0);
p1.SetDatabaseDefaults();
btr.AppendEntity(p1);
trans.AddNewlyCreatedDBObject(p1, true);
trans.Commit();
}
catch (System.Exception ex)
{
doc.Editor.WriteMessage("Error encountered: " + ex.Message);
trans.Abort();
//abort to roll out of excpetion for unreferenced object
}//end catch
}//end using
}//end drawpolylineElip
public double BulgeEquationTan(double angleD)
{
double tanV = ConvertToRadians(angleD) / 4;
double tanA = Math.Tan(tanV);
return tanA;
}//end BulgeEquationTan
public double ConvertToRadians(double angle)
{
return (Math.PI / 180) * angle;
}//end ConvertToRadians
}
}