qjchen 发表于 2010-8-10 23:51:00

[飞马系列] 个人的第一个F# JIG代码——截断线绘制

本帖最后由 qjchen 于 2013-10-20 19:29 编辑

个人的第一个F# JIG代码——截断线绘制

由于.NET编程一直似懂非懂,不过最近看了一些F#的介绍之后,对其颇有好感
于是啃了两天帮助
仔细阅读了才鸟兄的C# 五角星jig例子、KEAN的F# 螺旋线jig例子和AUTODESK公司的椭圆C# JIG例子
照葫芦画瓢地写下了如下一段简单的截断线例子
在此对以上作者表示衷心的感谢
而本人水平有限,代码非常不简洁,没有体现出F#的任何优点,各位见笑了,请不吝指教
后续希望能有所改进

源代码和项目如附件,内有说明
使用说明
(1) 可在AUTOCAD2007 或2011 中,用netload命令,加载这个myfirstjig.dll
   则可以通过命令 mybl来调用画截断线,效果可见gif文件


(2)源码使用说明:请用VS2008+F# 2.0安装包或者 VS2010打开
   注意:要修改引用中ACMGD.DLL和ACDBMGD.DLL的路径(重新删除再引用,并设置拷贝到本地为false)
               要修改项目属性中debug里面的acad.exe的路径(重新查找)
by qjchen
//本文参照了才鸟兄的五角星例子、KEAN的螺旋线例子和AUTODESK公司的椭圆JIG例子
//在此对他们表示衷心的感谢
//by qjchen@gmail.com 华南理工大学 2010.08.10
module File1_mod.Commands
//引入一些空间,类似C#的using
open System
open Autodesk.AutoCAD.ApplicationServices
open Autodesk.AutoCAD.DatabaseServices
open Autodesk.AutoCAD.EditorInput
open Autodesk.AutoCAD.Geometry
open Autodesk.AutoCAD.GraphicsInterface
open Autodesk.AutoCAD.Runtime
//根据才鸟兄实体书中的例子编写函数,仿LISP的polar
let PolarPoint (basePt:Point2d) (angle:double) (distance:double):Point2d=
    let point = Point2d(basePt.X+distance*Math.Cos angle,basePt.Y+distance*Math.Sin angle)
    point
//Ang2Rad,仿才鸟兄的函数,不过才鸟兄写成了rad2ang,或许是笔误?
let Ang2Rad (angle:double) =
    let rad=angle*Math.PI/180.0
    rad
//定义一个继承于DrawJig的JdxJig类
type JdxJig() as this = class
inherit DrawJig()
//此处定义的两个变量,一个来自于jdx的初始赋值,一个来自于起始点
let mutable (_pl : Polyline) = null
let mutable _startPt=new Point3d()
//member是这个类中的一个函数,仿Kean函数编写
member x.StartJig(ed:Editor,pt,pl) =
    //将之前获取的点及构造的函数赋予此两变量
    _startPt <- pt
    _pl <- pl
    //开始drag处理
    let stat = ed.Drag(this)
    //返回一个状态值
    stat
//重写sample函数,仿Kean的写法
override x.Sampler prompts =
    //获取输入点
    let jo = new JigPromptPointOptions()
    jo.UseBasePoint <- true
    jo.BasePoint <- _startPt
    jo.Cursor <- CursorType.Crosshair
    let respoi:PromptPointResult=prompts.AcquirePoint(jo)
    let curPt = respoi.Value
    let mutable endPt = new Point3d()
    if curPt <> endPt then
       //赋予起始点给p0,赋予当前移动点给p6
       let p0:Point2d = new Point2d(_startPt.X, _startPt.Y)
       let p6:Point2d = new Point2d(curPt.X, curPt.Y)
       //计算起始点和终止点的矢量和角度
       let vec:Vector2d = p6-p0
       let ang:double = vec.Angle
       //下面这几段写的真丑陋,没有一点F#简洁的特点,下一步来进行修改
       let mutable p1=new Point2d()
       let mutable p2=new Point2d()
       let mutable p3=new Point2d()
       let mutable p4=new Point2d()
       let mutable p5=new Point2d()
       let mutable p2a=new Point2d()
       let mutable p4a=new Point2d()
       let mutable d06:double = p6.GetDistanceTo(p0)
       //以下是截断线的画法,是按照1:100的比例画的,没有考虑比例问题
       if d06<=200.0 then
         p1<-p0
         p2<-p0
         p3<-p0
         p4<-p0
         p5<-p0
       else
         let ang1801= Ang2Rad 180.0+ang
         let ang901=Ang2Rad 90.0+ang
         let ang902=ang-Ang2Rad 90.0
         let d0605=0.5*d06
         p3<-PolarPoint p0 ang d0605
         p1<-PolarPoint p3 ang1801 100.0
         p2a<-PolarPoint p3 ang1801 50.0
         p2<-PolarPoint p2a ang901 200.0
         p5<-PolarPoint p3 ang 100.0
         p4a<-PolarPoint p3 ang 50.0
         p4<-PolarPoint p4a ang902 200.0
       _pl.SetPointAt(0, p0)
       _pl.SetPointAt(1, p1)
       _pl.SetPointAt(2, p2)
       _pl.SetPointAt(3, p3)
       _pl.SetPointAt(4, p4)
       _pl.SetPointAt(5, p5)
       _pl.SetPointAt(6, p6)
       endPt <- curPt;
       SamplerStatus.OK
    else
       SamplerStatus.NoChange;
//重写WorldDraw函数,仿Kean的写法,精简了一下
override x.WorldDraw (draw : WorldDraw) =
    draw.Geometry.Polyline(_pl, 0,6)
    |> ignore
    true
end

//下面是函数命令部分
[<CommandMethod("qjchen", "mybl", CommandFlags.Modal)>]
let jigjdx() =
// 开始常用语句
let doc =
    Application.DocumentManager.MdiActiveDocument
let ed = doc.Editor
let db = doc.Database
// 提示选择起始点
let startRes = ed.GetPoint("\nSelect first point: ")
if startRes.Status = PromptStatus.OK then
    let startPt = startRes.Value
    // 创建polyline和运行jig
    let pl:Polyline = new Polyline(7)
    for i=0 to 6 do
      pl.AddVertexAt(i, Point2d(0.0,0.0),0.0,0.0,0.0)
    let jig = new JdxJig()
    let res = jig.StartJig(ed, startPt, pl)
    if res.Status = PromptStatus.OK then
      use tr =
      db.TransactionManager.StartTransaction()
      // 得到块表和块记录
      let bt =
      tr.GetObject
          (db.BlockTableId,OpenMode.ForRead)
          :?> BlockTable
      let ms =
      tr.GetObject
          (bt.,
          OpenMode.ForWrite)
          :?> BlockTableRecord
      // 把截断线加入到模型空间
      let id = ms.AppendEntity(pl)
      tr.AddNewlyCreatedDBObject(pl, true)
      tr.Commit()

bearbear1 发表于 2010-8-11 17:52:00

<p>才鸟兄的C# 五角星jig例子</p>
<p>&nbsp;</p>
<p>在哪能看到</p>
<p>&nbsp;</p>
<p>F# 不了解</p>

qjchen 发表于 2010-8-11 19:39:00

[原创] 个人的第一个F# JIG代码——截断线绘制

<p>谢谢 lzh741206版主:)</p>
<p>&nbsp;</p>
<p>To bearbear1: 这个例子是来自于我买的一本实体书 《Autocad Vba &amp; Vb.net开发 基础与实例教程》:曾洪飞(网名才鸟),张帆(网名:zfbj),卢择临(ahlzl)几位高手写的书,几位高手也在明经上啊</p>
<p>&nbsp;</p>
<p>不过刚才看了具体章节,讲jig的第22章是ahlzl兄写的,那我前面写的才鸟的写法可能有误.......</p>
<p>&nbsp;</p>
<p>F#是函数式语言,有许多优点,我上面的写法是用最啰嗦的方法,无法体现其精髓,等我过些日子更熟悉一些再来改进。</p>
<p>&nbsp;</p>
<p>由于这是我用F#编的第二个CAD范例,第一个是画圆啊画线找BOUNGDINGBOX等简单操作,第二个就进入这个JIG的撰写,跳跃有点大。调试的时候开始也出现了几十个错误,改了半天。其实F#对空格、缩进等的要求都挺高,最好还是先用C#或者VB.NET来开发好些。只是做了小小的尝试,希望以后熟悉之后能好些。</p>

bearbear1 发表于 2010-8-14 11:40:00

<p>&nbsp; 回复的这么清楚,万分激动,</p>
<p>&nbsp;</p>
<p></p>

zjh2785 发表于 2018-3-30 17:19:57

很好的程序,就是F#看着头大。。。

ynhh 发表于 2021-12-10 14:16:05

我第一个学写的程序也是折断线
是四川德钢建筑工地上打工时自学的
只是没你这中途有动态显示这么高大上
但自我感觉还是实用
你这两端与指定点对齐与实用不太符合
实际中都是超出一小段的最后谢谢您的分享
祝您身体健康







页: [1]
查看完整版本: [飞马系列] 个人的第一个F# JIG代码——截断线绘制