[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
回复 15# 523066680


    谢谢热心的版版,我这个也不急的,这个是我的举例,如果数据量只有这么几个数的话,我用autocad也可以解决的,主要是大批量的判断,就非常难搞了

TOP

回复 14# tommytangtang

处理的是一般多边形, 在C代码中有测试用的多边形, 顶点坐标可以看出是一个 正4边形, 和一个 凹 8边形
  1. vec vsq[] = { {0,0}, {10,0}, {10,10}, {0,10},
  2. {2.5,2.5}, {7.5,0.1}, {7.5,7.5}, {2.5,7.5}};
  3. polygon_t sq = { 4, vsq }, /* outer square */
  4. sq_hole = { 8, vsq };      /* outer and inner square, ie hole */
复制代码

TOP

其实这个问题应该看这本书:《实时碰撞检测算法技术》而且我手上有一本,
当时纯粹手贱买下的,从来没看过……  http://www.tup.com.cn/book/Showbook.asp?CPBH=033422-01&DJ=52


第五章就有  点与多边形之间的测试、点与三角形之间的测试(多边形可以分为多个三角形)

TOP

按顶楼算法实现了基本功能,也不懂得到的结果是不是正确的,撸主搞个样本来比对下吧:
http://bbs.bathome.net/viewthread.php?tid=31486

TOP

回复 19# CrLf


    你把筛选的顶点分两批晒一下,我可以脚本绘图 (纯粹找事做)

TOP

回复 20# 523066680


    那敢情好,有劳您老人家了!

    顺便请教一下用什么脚本绘图比较方便

TOP

回复 21# CrLf

虽说Perl和python都有很多绘图接口,但是数据表达上的话还是python比较好用
不过我也忘了python怎么用了, =_= 正在用C语言+OPENGL绘图

TOP

回复 21# CrLf


    C.txt 有一个点在里面, 是哪个还不清楚[attach]7585[/attach]
    B.txt 的坐标全在外面
我自己抄了个算法,结果也不对,难道是绘图有问题?晕。

2014-08-18, 按碰撞检测算法书上的算法做了一个

C/C++的代码以及链接参考附件

Perl代码:
  1. use IO::Handle;
  2. STDOUT->autoflush(1);
  3. my $coordfile="a.txt";
  4. my @poly=(
  5.     96.802,87.23,
  6.     89.094,78.623,
  7.     92.268,64.808,
  8.     115.391,61.863,
  9.     124.913,77.265,
  10.     115.845,90.174,
  11.     102.696,92.439,
  12.     #96.802,87.23,
  13. );
  14. our @V;
  15. my $i=0;
  16. while (scalar(@poly)>0) {
  17.     $V[$i]{x}=shift @poly;
  18.     $V[$i]{y}=shift @poly;
  19.     $i++;
  20. }
  21. my ($x, $y);
  22. my %dot;
  23. open READ,"<",$coordfile or die "$!";
  24. open INPOLY, ">", "inside.txt" or die;
  25. open OUTPOLY, ">", "outside.txt" or die ;
  26. foreach (<READ>) {
  27.     ($x, $y, undef) = split(/ |,/, $_);
  28.     #print $x," , ",$y,"\n";
  29.     $dot{x} = $x;
  30.     $dot{y} = $y;
  31.     if (&pointInPolygon(\%dot) eq "true") {
  32.         print INPOLY "$x, $y\r\n";
  33.         print "($x, $y) in polygon\n";
  34.     } else {
  35.         print OUTPOLY "$x, $y\r\n";
  36.     }
  37. }
  38. close READ;
  39. close INPOLY;
  40. close OUTPOLY;
  41. sub pointInPolygon {
  42.     our @V;
  43.     my $p = shift;
  44.     my $npoints = $#V+1;
  45.     my ($low, $high) = (0, $npoints);
  46.     do {
  47.         $mid = ($low + $high) / 2;
  48.         $mid=int($mid)+1 if ($mid > int($mid));
  49.         if ( &TriangleIsCCW($V[0], $V[$mid], $p) eq "true" ) {
  50.             $low = $mid;
  51.         } else {
  52.             $high = $mid;
  53.         }
  54.     } while ( ($low + 1) < $high);
  55.     if( ($low == 0) or ($high == $npoints) ) {
  56.         #print "$npoints $low $mid $high\n";
  57.         return "false";
  58.     }
  59.     return &TriangleIsCCW($V[$low], $V[$high], $p);
  60. }
  61. sub TriangleIsCCW {
  62.     my ($p0, $p1, $p2) = @_;
  63.     my $cross;
  64.     my ($d0, $d1, $d2, $d3);
  65.     $d0 = ($p1->{x} - $p0->{x});
  66.     $d1 = ($p1->{y} - $p0->{y});
  67.     $d2 = ($p2->{x} - $p0->{x});
  68.     $d3 = ($p2->{y} - $p0->{y});
  69.     $cross = &Cross($d0, $d1, $d2, $d3);
  70.     if ($cross > 0) {
  71.         return "true";
  72.     } else {
  73.         return "false";
  74.     }
  75. }
  76. sub Cross {
  77.     #T Cross(T x0, T y0, T x1, T y1) {
  78.     #//|x0 y0| = |a b|
  79.     #//|x1 y1|   |c d|
  80.     #//ad * bc
  81.     #//x0 * y1 - x1 * y0
  82.     my ($x0, $y0, $x1, $y1) = @_;
  83.     my $result;
  84.     $result = ($x0 * $y1) - ($y0 * $x1);
  85.     return $result;
  86. }
复制代码
在区域范围内的点:
100.477, 85.911
96.747, 84.002
96.817, 75.030
105.692, 67.907
97.253, 70.233
111.950, 80.117
105.931, 76.600
111.138, 85.624
114.157, 74.060

TOP

回复 23# 523066680


    结果不对啊,挑出来的坐标和之前我给的a.txt都对不上了,之前给的x没有小于10的,基本都是50以上
版主绘图没问题,我打印到图上也和你一样的
图中,红色的点是a.txt。蓝色的点是得到的结果。

TOP

本帖最后由 523066680 于 2014-8-18 16:09 编辑

回复 24# tommytangtang


这里面分明没有小于10的
100.477, 85.911
96.747, 84.002
96.817, 75.030
105.692, 67.907
97.253, 70.233
111.950, 80.117
105.931, 76.600
111.138, 85.624
114.157, 74.060

第一张图是昨晚的。第二张图才是今天的

TOP

回复 23# 523066680


昨天刚好看到书上说可以把:
  1. my $result;
  2. $result = ($x0 * $y1) - ($y0 * $x1);
  3. return $result;
复制代码
简化成:
  1. ($x0 * $y1) - ($y0 * $x1);
复制代码

TOP

本帖最后由 523066680 于 2014-8-18 18:41 编辑

回复 26# CrLf


  谢谢提醒,昨天手工将C转Perl后BUG一堆,所以很谨慎地把句子分开了 =_=

就是这里有个取反…… 然后return cross > 0  真精简……
  1. template<class T>
  2. bool triangleIsCCW(
  3. T x0, T y0,
  4. T x1, T y1,
  5. T x2, T y2) {
  6. auto cross = -(Cross<T>(x1-x0,y1-y0,x2-x0,y2-y0));
  7. return cross > 0;
  8. }
复制代码

TOP

测试点与凸多边形的关系,纯C版本

本帖最后由 523066680 于 2014-8-18 21:33 编辑
  1. #include <stdio.h>
  2. #define bool int
  3. #define false 0
  4. #define true 1
  5. typedef struct {
  6. float x;
  7. float y;
  8. } Point;
  9. Point poly[]={
  10.     96.802,87.23,
  11.     89.094,78.623,
  12.     92.268,64.808,
  13.     115.391,61.863,
  14.     124.913,77.265,
  15.     115.845,90.174,
  16.     102.696,92.439,
  17. };
  18. float Cross(
  19.     float x0, float y0,
  20.     float x1, float y1
  21. ) {
  22.     return (x0 * y1) - (x1 * y0);
  23. }
  24. int triangleIsCCW( //判断三个点的顺序是否为逆时针
  25.     Point P0, Point P1, Point P2
  26. ) {
  27.     auto cross = (
  28.         Cross(
  29.             P1.x-P0.x, P1.y-P0.y,
  30.             P2.x-P0.x, P2.y-P0.y
  31.         )
  32.     );
  33.     return cross >= 0;
  34. }
  35. bool pointInPolygon(
  36.     Point vip, Point poly[], int n_poly
  37. ) {
  38.     // points represented by [(x0,y0), ... (xn,yn)]
  39.     int low = 0,  high = n_poly;
  40.     int mid;
  41.     do {
  42.         mid = (low + high) / 2;
  43.         if (
  44.             triangleIsCCW(poly[0], poly[mid], vip)
  45.         ) {
  46.             low = mid;
  47.         } else {
  48.             high = mid;
  49.         }
  50.     } while (low + 1 < high);
  51.     if (low == 0 || high == n_poly) return false;
  52.     return triangleIsCCW(poly[low], poly[high], vip);
  53. }
  54. int main(int argc, char *argv[])
  55. {
  56.     FILE *fp = fopen("a.txt","r");
  57.     FILE *wrt = fopen("inside.txt","w");
  58.     Point vip;
  59.     char s[1024];
  60. int n_poly = (sizeof(poly) / sizeof(poly[0].x)) / 2;
  61. int in_polygon;
  62.     while ( ! feof(fp) ) {
  63.         fgets(s, 1024, fp);
  64.         if ( sscanf(s, "%f %f", &vip.x, &vip.y) < 2 ) {
  65.             sscanf(s, "%f,%f", &vip.x, &vip.y);
  66.         }
  67.         in_polygon = pointInPolygon(vip, poly, n_poly);
  68.         if ( in_polygon ) {
  69.             printf("%.3f, %.3f\n", vip.x, vip.y);
  70.             fprintf(wrt, "%.3f, %.3f\n", vip.x, vip.y);
  71.         }
  72.     }
  73.     fclose(fp);
  74.     fclose(wrt);
  75.     return 0;
  76. }
复制代码
算法来自《实时碰撞检测算法技术》5.4.1  点与多边形之间的测试  P139


这段C的处理结果和Perl又那么一两个点的误差,主要是有些点几乎就在边缘上,
零点零几的区别 和 0 判断产生不同的结果。
────────┐
100.477, 85.911 │
96.747, 84.002  │
96.817, 75.030  │
105.692, 67.907 │
97.253, 70.233  │
115.392, 61.864 │
111.950, 80.117 │
105.931, 76.600 │
111.138, 85.624 │
114.157, 74.060 │
120.702, 70.397 │
92.268, 64.808  │
115.391, 61.863 │
────────┘

TOP

回复 3# tommytangtang


    vbs 就是 visual basic script

TOP

回复 29# DAIC


    少将,你为何有两颗太阳!

TOP

返回列表