明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
楼主: Gaudi

[讨论] 新手从零开始的第一份LISP程序全纪录

    [复制链接]
发表于 2024-4-23 12:25:54 | 显示全部楼层
点赞点赞,学习一下

点评

一起学习,还在继续更新中  发表于 2024-5-9 19:43
发表于 2024-4-23 14:01:09 | 显示全部楼层
可以,对新手友好。

点评

是的,主要就是为了帮助到像我一样的新手lisp玩家  发表于 2024-5-9 19:44
发表于 2024-4-23 14:41:21 | 显示全部楼层
收藏起来~蛮不错呢~
学习中~

点评

谢谢支持,一起学习,会一直更新到结尾  发表于 2024-5-9 19:45
 楼主| 发表于 2024-4-23 16:47:39 | 显示全部楼层
本帖最后由 Gaudi 于 2024-4-25 02:44 编辑

第二篇  第二部分  读取主线起点并计算起点角度




要加点强度了,这一部分我开始涉及到vla函数。

前文说到vla函数本质上是将cad中的图元转变为大佬微软建立的com平台上。
那么这里就涉及到指向和转变的函数。
你得先跟电脑说,我要将这个东西转一下吧?

我最常用的就两个,其他碰到需求再说:
<entsel>和<entlast>。
<entsel>意思是entity select的意思,实体选择。
<entlast>意思是entity last的意思,最近一次创造的实体。
其他你先别看。

不管是自己选、还是电脑选,选中了以后,通过<VLAX-ENAME->VLA-OBJECT>,即可转变为vla实体。
还是得通过<setq>定义一下,你转变了不定义,接下来也没法调用是吧?

照样给个示例:
  1. (setq OBJCenterLine (VLAX-ENAME->VLA-OBJECT centerLine))

这就把通过<entsel>获得的centerLine,转变为vla实体OBJCenterLine了。

转变为VLA实体有什么好处呢?
前文说过,三种情况:
A 各软件之间数据的连接必须用
B 相比传统办法更加简单清晰
C 传统办法不能达成需求




1 获得起点坐标

这次就是B情况。
给大家看看用VLA函数怎么获得起点。
  1. (setq starPoint (VLAX-CURVE-GETSTARTPOINT OBJCenterLine))


好了。
好了?
好了。

不用去判断是多段线还是SPL线,不需要用各种循环啥的。
反正我是因为查过,所以才不想用了。

并且vla函数有个特点,你别看它长,其实它很软。
它能干啥都给你写得清清楚楚。

VLAX-CURVE-GETSTARTPOINT
定义-  曲线  -获得 起始   点

简直把大爷来用啊写在脸上了。




2 求得起点的切线角度

要想进行下一步标注,得求得起点处垂直曲线的角度。
而垂直曲线的角度,可以通过这个点切点角度换算。
所以问题转化为求得曲线起点的切线。

首先第一个函数,<VLAX-CURVE-GETPARAMATPOINT>。(定义-曲线-获得 参数 在 点)
这个函数的解释很晦涩,我仔细理解以后发现:
这不就是<VLAX-ENAME->VLA-OBJECT>吗?
只不过是将曲线和点结合起来而已。

【叠甲:这只是个人的、错误的理解】

然后获得点的VLA对象以后,再使用<VLAX-CURVE-GETFIRSTDERIV>。(定义-曲线-获得 一阶 导数)
这返回的是一个向量。
切线嘛,肯定是一个有指向性的参数。

最终的结果是:
  1.   (setq  V1 (VLAX-CURVE-GETFIRSTDERIV ENAME (VLAX-CURVE-GETPARAMATPOINT ENAME Point)))


在切点加上返回的向量,就得到切线了!

这里要用到一个运算函数<mapcar>。
照样给个实例:
  1. (mapcar '1+ '(10 11 12))

返回(11 12 13)。

<mapcar> 函数后面要再跟一个函数,这是<mapcar>定义需求得。
最后的结果是:
  1. (setq P1 (MAPCAR '+ Point V1))

打上<'>,作用是将 + 符号作为一个函数名传递给 MAPCAR,而不是对 + 进行求值。
通过使用单引号 ',告诉 AutoLISP 将 + 作为一个符号(函数名)原封不动地传递给 MAPCAR,而不对其进行求值。
这样,MAPCAR 就知道要使用 + 函数来处理列表中的元素。

因此,(MAPCAR '+ Point V1) 的作用是将 Point 与 V1 列表中对应位置的元素相加,生成一个新的点 P1。
这实现了将点 Point 沿着向量 V1 的方向进行平移的功能。

然后,将这个平移后的点,赋值给P1。
那么P1和point,就组成了Point这个点的切线。

结束。




3 总结

有点绕晕了啊……
再总结下。

A 将主线转为VLA对象。<VLAX-ENAME->VLA-OBJECT>
B 获取主线的起始点。<VLAX-CURVE-GETSTARTPOINT>
C 将起始点和曲线结合起来。<VLAX-CURVE-GETPARAMATPOINT>
D 获得起始点的一阶导数,也就是切线向量。<VLAX-CURVE-GETFIRSTDERIV>
E 将起始点沿着切线向量移动。(MAPCAR '+ Point V1)
F 获得切点角度。(setq pointAngle (ANGLE Point P1))

还是挺顺畅的。

就我个人感觉,VLA函数麻烦的不是使用,而是……
根本不知道有这个函数啊!
也不知道这个函数能干啥啊!

但是用起来是真爽啊,简单清晰,接近自然语言了。
毕竟都给封装好了。




4 代码实现

  1. (DEFUN angleCAL (ENAME Point)
  2.   (setq V1 (VLAX-CURVE-GETFIRSTDERIV ENAME (VLAX-CURVE-GETPARAMATPOINT ENAME Point)))
  3.   (setq P1 (MAPCAR '+ Point V1))
  4.   (setq pointAngle (ANGLE Point P1))
  5.   pointAngle
  6. )



这个代码还可以满足其他需求。
比如画切线啊什么的。

反正已经拿到两个点了。


发表于 2024-4-23 17:27:05 | 显示全部楼层
为大佬点赞

点评

你客气了,不是什么大佬,纯粹是一个LISP新手  发表于 2024-5-9 19:46
 楼主| 发表于 2024-4-23 17:29:09 | 显示全部楼层
本帖最后由 Gaudi 于 2024-4-25 11:08 编辑

第二篇  第二部分  增补



1 关于<mapcar>

再把我的思考说一下。
<mapcar>后面跟一个函数,意思告诉程序,对后面列表中的每个参数都执行一次这个函数,最后返回一个列表结果。

很多大佬会将<mapcar>和<lambda>连用。
<lambda>是匿名函数的意思。

就是本来在这个地方,你得给程序传递个函数名。
但是为了这么点操作我新建个函数,实在懒得搞。
那就用不定义名称的函数给你嘛。


lambda就是λ。
为什么用这个希腊字母代表匿名函数呢?
那就要扯蛮多了,从lambda演算开始说起。
最有意思的回答是这个:
Russell 与 Whitehead 的《Principia Mathematica》中用 2x(上^) +1来表示 f(x)= 2x +1中的f。Church 原本要引入的表示法是x(上^).2x +1,但是打字员未能将尖号放在 x 之上,而是放在了 x 之前,于是成了^x.2x +1,然后又被另一个打字员改成了 λx.2x +1.



扯远了扯远了。

文中代码如果改写成<lambda>,应该是这样:
  1. (setq P1 (MAPCAR '(lambda (p v) (+ p v)) Point V1))

先定义一个匿名函数,这个函数有两个参数,函数的操作是把这两个参数相加。


2 VLA函数

为什么觉得VLA函数复杂,一个原因是因为它的函数名贼长。
但现在来看,这反而是它的特性。
它在尽可能得用自然语言去描述这个函数的功能。
那就没办法了。

最大的困难实际上是不知道有这么个VLA函数。
因为自然语言描述一个功能,谁都会。

但鬼知道有没有这么个VLA函数能实现这个功能?
或者能通过几个现有的VLA函数组合起来实现这个功能?

比如后来我才发现有这么一个函数,叫<VLAX-CURVE-GETTANATPOINT>.(定义-曲线-获得 切线 在 点)
传递好曲线和点以后,直接返回切线。
直接一步到位了属于是。


但是……
这个函数是我瞎编的。


总归VLA函数在我看来属于偏向于自然语言一点的,应该是程序内部封装了大量代码。
要熟悉它也没别的办法,多用吧。


3 关于<VLAX-CURVE-GETPARAMATPOINT>的进一步思考

通过<VLAX-CURVE-GETSTARTPOINT>获得起始点坐标后,为什么不能直接用<VLAX-CURVE-GETFIRSTDERIV>获得切线向量呢。

因为一条曲线上有无限条切线;通过一个点的直线有无线条。

所以单独定义一条曲线或者一个点,都不能确定一条准确的切线。

只有将曲线和点结合起来,才能确定唯一一条切线。

这就是<VLAX-CURVE-GETPARAMATPOINT>的作用。


发表于 2024-4-23 20:39:04 | 显示全部楼层
VLIDE很难用,而且还会假死,
我调试是在特定位置写一个alert,等弹出窗口的时候,使用鼠标预览变量里面的值,也基本能解决问题。
发表于 2024-4-24 12:41:39 | 显示全部楼层
牛逼,注册第3天都已经开始上手了,收藏了,有空了看看学习心得

点评

毕竟不想加班 就得啃这个硬骨头,也没办法  发表于 2024-5-9 19:47
发表于 2024-4-24 14:00:58 | 显示全部楼层
你有种再说一遍 发表于 2024-4-22 18:40
你可以用md格式写笔记.
只是这个论坛不支持这个格式.
并且再去学习一下git,它支持md格式

有啥支持MD语法的论坛吗
发表于 2024-4-24 19:33:14 | 显示全部楼层
tranque 发表于 2024-4-24 14:00
有啥支持MD语法的论坛吗

论坛貌似没有,但是可以导出html的,而且博客类很多支持md
回复 支持 1 反对 0

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-11-25 18:38 , Processed in 0.155038 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表