乐筑天下

搜索
欢迎各位开发者和用户入驻本平台 尊重版权,从我做起,拒绝盗版,拒绝倒卖 签到、发布资源、邀请好友注册,可以获得银币 请注意保管好自己的密码,避免账户资金被盗
查看: 38|回复: 19

[编程交流] Lisp在GP之间绘制一条线

[复制链接]

1

主题

8

帖子

7

银币

初来乍到

Rank: 1

铜币
5
发表于 2022-7-6 07:41:08 | 显示全部楼层 |阅读模式
你好
 
我试着写一个lisp在两个GPs点之间画一条线,它们之间的距离是用havesine公式计算的,但我得到了一个错误[;错误:错误的参数类型:consp“56.06613,3.4514”],我认为它由于某种原因无法识别坐标,有人能帮我吗。
我开始为自己写这个lisp是为了好玩,因为我有一部智能手机,可以从中提取GPS坐标,我想看看是否可以更准确地测量花园的大小
我不得不承认我是一个Lisp程序写作的乞丐。
 
 
顺致敬意,
克里斯蒂安
 
 
 
 
  1. ;draw real distances from GPS coordinates
  2. ;load points from csv files
  3. (Defun C:gpsd ( / dataL csv_name ofil rd-pos n Pi1 P1 cntr P2n ang ED lat1 lat2 Dlat Dlong a c RD ent entdata)
  4. ;*******************load files***************
  5. (setq dataL '());define an empty list
  6. (setq csv_name "");define an empty name for file
  7. (setq csv_name (getfiled "Select Point List .csv file" "" "csv" 2));get the file name
  8. (setq ofil (open CSV_name "r")); define "ofile" as open the file
  9. (while (setq rd-pos (read-line ofil));read each line from file
  10. (setq dataL (cons rd-pos dataL));add each row to list
  11. );close while
  12. (close ofil);close file
  13. (setq dataL (reverse dataL));put list in right order
  14. (setq n (length dataL));get the number of points
  15. (setq Pi1 (nth 0 dataL));get initial GPS point
  16. (setq P1 '(0 0));set initial Real point to "0,0"
  17. (setq xi1 (car Pi1));get initial x from first point
  18. (setq yi1 (cadr Pi1));get initial y from first point
  19. (setq cntr 1)
  20. (while (<= cntr n)
  21. (setq P2n (nth cntr dataL));choose second GPS point by cntr
  22. (setq Pxn (car P2n));get x from second point
  23. (setq Pyn (cadr P2n));get y from second point
  24. (setq ang (angle Pi1 P2n));get angle between points
  25. (setq ang (* 180.0 (/ ang pi)));convert angles from radians to degrees
  26. ;calculate real distance
  27. (setq ED 6371000);earth diameter in metres
  28. (setq lat1 (* pi (/ xi1 180.0)));lat in rad
  29. (setq lat2 (* pi (/ Pxn 180.0)))
  30. (setq Dlat (* pi(/ (- Pxn xi1) 180.0)))
  31. (setq Dlong (* pi(/ (- Pyn yi1) 180.0)))
  32. (setq a (+ (sin(/ 2 Dlat)^2) (* (* (cos lat1) (cos lat2)) (sin (/ 2 Dlong)^2))))
  33. (setq c (* 2 (atan (sqrt a) (sqrt (- 1 a)))));calculate earth angle
  34. (setq RD (* ED c));calculate real distance between GPs Points
  35. (setq RD (* RD 1000));convert distance from metres to mm
  36. (setq P2 (polar P1 ang RD));calculate Real P2 by distance and angle
  37. (command ".line" P1 P2 "");draw a line as real distance between GPS points
  38. (setq ent (entlast));select last entoty created
  39. (setq entdata (entget ent));extract info from it
  40. (setq P1 (cdr (assoc 11 entdata)));reset Real P1 as (X2,Y2) from last line
  41. (setq Pi1 P2n);reset GPS Pi1 as next point
  42. (setq xi1 (car Pi1));recalculate x from new point
  43. (setq yi1 (cadr Pi1));recalculate y from new point
  44. ;reset counter
  45. (setq cntr (+ 1 cntr))
  46. );close while loop
  47. );close lisp
回复

使用道具 举报

4

主题

2143

帖子

2197

银币

限制会员

铜币
-24
发表于 2022-7-6 07:45:05 | 显示全部楼层
谢谢,我明天会试试Marko的版本,我想我是从csv中读取每一行,作为每个点的坐标列表,显然我错了。
 
当做
克里斯蒂安
回复

使用道具 举报

5

主题

1334

帖子

1410

银币

限制会员

铜币
-20
发表于 2022-7-6 07:48:03 | 显示全部楼层
我再次需要你的帮助,这次我相信角度是负值,我的程序停止了,我试图用“abs”强迫我的计算得到正值,但仍然没有结果
我也改变了我的代码,我现在计算相对于第一个点的距离,得到真正的x和y,我把它们存储到一个列表中,最后我想画一条线来连接所有的点。
 
  1. ;draw real distances from GPS coordinates
  2. ;load points from csv files
  3. (Defun C:gpsd ( / Xcoord Ycoord dataL csv_name ofil rd-pos n Pi1 P1 cntr P2n ang ED lat1 lat2 Dlat Dlong a c RD ent entdata)
  4. ;*******************load files***************
  5. (setq dataL '());define an empty list
  6. (setq csv_name "");define an empty name for file
  7. (setq csv_name (getfiled "Select Point List .csv file" "" "csv" 2));get the file name
  8. (setq ofil (open CSV_name "r")); define "ofile" as open the file
  9. (while (setq rd-pos (read-line ofil));read each line from file
  10. [highlight]
  11. (setq Xcoord (substr rd-pos 1 (vl-string-position (ascii ",") rd-pos)))
  12. (setq Ycoord (substr rd-pos (+ (vl-string-position (ascii ",") rd-pos) 2) (- (strlen rd-pos) (vl-string-position (ascii ",") rd-pos) 1)))
  13. (setq dataL (cons (list (read Xcoord) (read Ycoord)) dataL));add each row to list
  14. [/highlight]
  15. );close while
  16. (close ofil);close file
  17. (setq dataL (reverse dataL));put list in right order
  18. (setq n (length dataL));get the number of points
  19. (setq Pi1 (nth 0 dataL));get initial GPS point
  20. (setq P1 '(0 0));set initial Real point to "0,0"
  21. (setq xi1 (car Pi1));get initial x from first point
  22. (setq yi1 (cadr Pi1));get initial y from first point
  23. (setq cntr 1)
  24. (while (<= cntr n)
  25. (setq P2n (nth cntr dataL));choose second GPS point by cntr
  26. (setq Pxn (car P2n));get x from second point
  27. (setq Pyn (cadr P2n));get y from second point
  28. (setq ang (angle Pi1 P2n));get angle between points
  29. (setq ang (* 180.0 (/ ang pi)));convert angles from radians to degrees
  30. ;calculate real distance
  31. (setq ED 6371000);earth diameter in metres
  32. (setq lat1 (* pi (/ xi1 180.0)));lat in rad
  33. (setq lat2 (* pi (/ Pxn 180.0)))
  34. (setq Dlat (* pi(/ (- Pxn xi1) 180.0)))
  35. (setq Dlong (* pi(/ (- Pyn yi1) 180.0)))
  36. [highlight](setq a (+ (expt (sin (/ 2 Dlat)) 2) (* (* (cos lat1) (cos lat2)) (expt (sin (/ 2 Dlong)) 2))))[/highlight]
  37. (setq c (* 2 (atan (sqrt a) (sqrt (- 1 a)))));calculate earth angle
  38. (setq RD (* ED c));calculate real distance between GPs Points
  39. (setq RD (* RD 1000));convert distance from metres to mm
  40. (setq P2 (polar P1 ang RD));calculate Real P2 by distance and angle
  41. (command ".line" P1 P2 "");draw a line as real distance between GPS points
  42. (setq ent (entlast));select last entoty created
  43. (setq entdata (entget ent));extract info from it
  44. (setq P1 (cdr (assoc 11 entdata)));reset Real P1 as (X2,Y2) from last line
  45. (setq Pi1 P2n);reset GPS Pi1 as next point
  46. (setq xi1 (car Pi1));recalculate x from new point
  47. (setq yi1 (cadr Pi1));recalculate y from new point
  48. ;reset counter
  49. (setq cntr (+ 1 cntr))
  50. );close while loop
  51. );close lisp

而不是:
  1. ...
  2. (setq Pi1 (nth 0 dataL));get initial GPS point
  3. (setq P1 '(0 0));set initial Real point to "0,0"
  4. [color=red](setq xi1 (car Pi1));get initial x from first point
  5. (setq yi1 (cadr Pi1));get initial y from first point[/color]
  6. ...
回复

使用道具 举报

35

主题

2471

帖子

2447

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
174
发表于 2022-7-6 07:52:28 | 显示全部楼层
问题在于平方根只对正数有意义;至少在一种情况下,论点是否定的。
  1. ;draw real distances from GPS coordinates
  2. ;load points from csv files
  3. (Defun C:gpx ( / Xcoord Ycoord dataL Rpt csv_name ofil rd-pos n Pi1 P1 cntr P2n ang ED lat1 lat2 Dlat Dlong a c RD ent entdata)
  4. ;*******************load files***************
  5. (setq dataL '());define an empty list
  6. (setq Rpt '());define an empty list for points
  7. (setq csv_name "");define an empty name for file
  8. (setq csv_name (getfiled "Select Point List .csv file" "" "csv" 2));get the file name
  9. (setq ofil (open CSV_name "r")); define "ofile" as open the file
  10.    (while (setq rd-pos (read-line ofil));read each line from file
  11.        (setq Xcoord (substr rd-pos 1 (vl-string-position (ascii ",") rd-pos)))
  12.        (setq Ycoord (substr rd-pos (+ (vl-string-position (ascii ",") rd-pos) 2) (- (strlen rd-pos) (vl-string-position (ascii ",") rd-pos) 1)))
  13.        (setq dataL (cons (list (read Xcoord) (read Ycoord)) dataL));add each row to list
  14.    );close while
  15. (close ofil);close file
  16. (setq dataL (reverse dataL));put list in right order
  17. (setq n (length dataL));get the number of points
  18. (setq Pi1 (nth 0 dataL));get initial GPS point
  19. (setq P1 '(0 0));set initial Real point to "0,0"
  20. (setq xi1 (car Pi1));get initial x from first point
  21. (setq yi1 (cadr Pi1));get initial y from first point
  22. (setq Rpt (cons P1 Rpt));add P1 on list as 0,0
  23. (setq cntr 1)
  24. (while (<= cntr n)
  25.    (setq P2n (nth cntr dataL));choose second GPS point by cntr
  26.    (setq Pxn (car P2n));get x from second point
  27.    (setq Pyn (cadr P2n));get y from second point
  28.    (setq ang (angle Pi1 P2n));get angle between points
  29.    (setq ang (* 180.0 (/ ang pi)));convert angles from radians to degrees
  30. ;calculate real distance
  31.   (setq ED 6371000);earth diameter in metres
  32.   (setq lat1 (abs(* pi (/ xi1 180.0))));lat in rad
  33.   (setq lat2 (abs(* pi (/ Pxn 180.0))))
  34.   (setq Dlat (abs (* pi(/ (- Pxn xi1) 180.0))));abs added
  35.   (setq Dlong (abs (* pi(/ (- Pyn yi1) 180.0))));abs added
  36.   (setq a (+ (expt (sin (/ 2 Dlat)) 2) (* (* (cos lat1) (cos lat2)) (expt (sin (/ 2 Dlong)) 2))))
  37.   (setq c (* 2 (atan (sqrt a) (sqrt (- 1 a)))));calculate earth angle
  38.   (setq RD (* ED c));calculate real distance between GPs Points
  39.   (setq RD (* RD 1000));convert distance from metres to mm
  40.   (setq P2 (polar P1 ang RD));calculate Real P2 by distance and angle
  41.   (setq Rpt (cons P2 Rpt));add next point to the list  
  42. ;reset counter
  43. (setq cntr (+ 1 cntr))
  44. );close while loop
  45. (setq Rpt (reverse RPT));put the list in the right order
  46. (command ".line" Rpt "");draw a line as real distance between GPS points
  47. );close lisp

你应该再次验证你的公式-我无法检查它们,因为我不知道它们来自哪里。
 
(至少第一个)故障制造者数据对是:
回复

使用道具 举报

1

主题

8

帖子

7

银币

初来乍到

Rank: 1

铜币
5
发表于 2022-7-6 07:56:59 | 显示全部楼层
 
 
这是哈弗森公式,你可以在这里找到更多细节。
 
 
谢谢
克里斯蒂安
回复

使用道具 举报

1

主题

8

帖子

7

银币

初来乍到

Rank: 1

铜币
5
发表于 2022-7-6 08:00:12 | 显示全部楼层
我改变了你家的路。csv-添加了“,”作为分隔符,我在球体上绘制地球和平地面的第一个代码完成了这项工作,但第二个代码给出了错误的结果,因为有许多土壤无法联合,然后与球体相交,形成一个1米厚的外壳。。。
 
这是我的代码和你的csv-由我修改。。。
 
您好,M.R。
 
P、 我已经用EvgeniElpanov的三角剖分法来确定区号,但在你们的例子中并没有用,你们必须找到其他方法来确定面积。。。
 
  1. [s][color=red](while (<= cntr n)[/color][/s]
  2. (while (< cntr n)
  1. [s][color=red](command ".line" Rpt "")[/color][/s]
  2. (command "_.LINE")
  3. (foreach point Rpt
  4. (command "_non" point)
  5. )
  6. (command "")

home road csv。先生txt文件
gpspronsph。lsp
gpsareasph。lsp
回复

使用道具 举报

35

主题

2471

帖子

2447

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
174
发表于 2022-7-6 08:00:31 | 显示全部楼层
虽然不是很精确,但我确实得到了ab区域的数据。。。大约75公顷。。。
 
试试看,这是我的第二个代码:
 
  1. (ascii "\t")
M.R。
gpsareasph新。lsp
回复

使用道具 举报

1

主题

8

帖子

7

银币

初来乍到

Rank: 1

铜币
5
发表于 2022-7-6 08:06:19 | 显示全部楼层
这很管用,但在这种情况下,我的计算机上的这些GPS坐标不会生成区域对象,因此它无法按预期完成操作。。。但我认为这是最好的解决方案,因为它在计算面积方面是最精确的。。。不过,如果GPS坐标接近赤道,可能无法与曲面形成立体,并且面之间不会相互干扰。。。这仅适用于2012和+(使用SURFSCULPT命令):
 
  1. (ascii "\,")

 
M、 R。
gpsareasph new new。lsp
回复

使用道具 举报

35

主题

2471

帖子

2447

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
174
发表于 2022-7-6 08:07:39 | 显示全部楼层
你好,Marko,
 
谢谢你的代码,我已经全部试用过了,我将使用“gpsareasph-new.lsp”‎“因为我只有AutoCad 2009和”gpsareasph new new。lsp‎“不起作用,但我会保留它,也许有一天我会有2012年。
 
再次感谢,
克里斯蒂安
回复

使用道具 举报

35

主题

2471

帖子

2447

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
174
发表于 2022-7-6 08:11:15 | 显示全部楼层
 
 
谢谢Marko,
 
我已经尝试了你的所有代码,但这一个对我来说最合适,因为我只有Autocad 2009,正如你所说,你的最后一个代码对我来说还不合适,也许有一天我会有2012版本。
 
再次感谢,
克里斯蒂安
回复

使用道具 举报

发表回复

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

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

QQ|关于我们|小黑屋|乐筑天下 繁体中文

GMT+8, 2025-3-9 22:17 , Processed in 0.474923 second(s), 72 queries .

© 2020-2025 乐筑天下

联系客服 关注微信 帮助中心 下载APP 返回顶部 返回列表