我有一个网格骨架,需要确定网格的方向,所以我可以自动在3d空间中正确定位。
我真的不知道如何获得最佳的线条,所以我可以自动从点组中定位它。 下面是它应该如何看待以及样本数据集的示例。
//skeleton vertices
vertices = [ 2.06104, 318.734, -149.29;
4.2207, 212.092, -145.141;
4.23213, 200.135, -144.811;
4.16573, 95.1567, -133.954;
4.7053, 126.626, -138.59;
4.16915, 171.645, -143.646;
4.18659, 183.173, -144.185;
4.17842, 179.964, -144.008;
2.76537, 288.063, -147.215;
-1.71817, 61.155, -124.25;
-0.492168, 66.2098, -127.702;
2.07608, 79.5012, -131.886;
4.03249, 238.699, -146.141;
4.23595, 206.822, -145.001;
4.23623, 203.704, -144.908;
4.17145, 220.543, -145.415;
4.12453, 228.514, -145.761;
2.41377, 301.021, -147.804;
4.03098, 236.064, -145.985;
2.48681, 298.432, -147.685;
4.68192, 129.093, -138.873;
2.65048, 292.424, -147.406;
4.54555, 104.737, -135.116;
-4.23707, 53.6538, -113;
1.93508, 317.106, -148.755;
-4.98045, 51.9036, -109.052;
-5.87157, 49.9703, -104.104;
-11.2433, 41.1865, -71.6569;
-15.1283, 30.7528, -33.5845;
-14.6647, 26.7291, -17.9213;
-13.1176, 23.9812, -5.55431;
-8.27057, 20.6161, 13.9826;
-4.49387, 19.0295, 25.4537;
4.5645, 139.344, -140.275;
-3.3737, 56.0265, -117.133;
4.21667, 192.056, -144.576;
3.99948, 93.2911, -133.447;
4.22894, 209.986, -145.081;
4.17824, 167.633, -143.406;
3.94993, 243.303, -146.26;
4.20391, 188.412, -144.431;
4.20673, 214.944, -145.239;
3.82056, 248.85, -146.382;
3.75634, 252.761, -146.523;
3.46093, 268.466, -147.033;
4.11554, 230.181, -145.836;
4.44799, 147.962, -141.303;
4.205, 165.551, -143.138;
4.7514, 117.603, -137.34;
4.25931, 161.613, -142.739;
4.15939, 222.571, -145.502;
4.38497, 152.519, -141.797;
3.12906, 279.268, -147.181;
3.05571, 282.333, -147.279;
-8.35374, 45.7208, -89.6802;
-6.43016, 19.7295, 20.0489;
3.51218, 265.85, -146.95;
4.22735, 196.569, -144.716;
3.60114, 261.275, -146.806;
3.87527, 245.264, -146.243;
3.70115, 255.948, -146.633;
3.33032, 273.433, -147.142;
4.14712, 224.649, -145.592;
4.11102, 231.178, -145.882;
4.17545, 177.258, -143.86;
4.07209, 234.491, -145.985;
4.13698, 226.37, -145.667;
4.50243, 144.003, -140.851;
4.74996, 120.215, -137.661;
3.00397, 283.765, -147.29;
4.22263, 164.279, -143.008;
4.19542, 216.684, -145.284;
4.74419, 122.387, -138.079;
4.24362, 162.754, -142.854;
4.1921, 217.204, -145.299;
3.1988, 276.954, -147.144;
2.24673, 307.266, -148.14;
4.70408, 113.726, -136.704;
1.55558, 75.9859, -131.562;
4.66136, 131.166, -139.157;
3.69856, 90.4963, -133.113;
4.42481, 149.643, -141.489;
2.02224, 313.586, -148.445;
3.39344, 270.742, -147.067;
-11.4507, 40.824, -70.2682;
-12.6325, 23.3651, -2.57932;
-7.10479, 20.0528, 17.8335;
-5.64725, 19.4808, 22.078;
-4.64392, 19.0822, 25.039;
2.02817, 318.148, -149.125;
2.33964, 303.688, -147.933;
3.66401, 257.998, -146.701;
4.63971, 109.538, -135.974;
1.92836, 315.331, -148.48;
-14.1808, 25.5312, -12.8091;
-9.41149, 21.1265, 10.4194;
-4.95978, 19.1884, 24.1908;
2.59159, 294.625, -147.508;
2.13575, 310.184, -148.256;
2.70921, 290.146, -147.303;
4.27225, 160.675, -142.644;
4.26101, 97.2627, -134.029;
4.48821, 103.188, -134.891;
4.49926, 103.485, -134.935;
-7.047, 47.7435, -97.5736;
-6.3594, 48.9598, -101.483;
-9.77383, 43.5659, -81.0321;
-8.9763, 44.7772, -85.911;
-10.8234, 41.8961, -74.4074;
-13.9937, 35.5167, -50.7962;
-14.3038, 34.7247, -47.9571;
-14.8257, 32.9699, -41.6747;
-14.6745, 33.5497, -43.7501;
-11.2159, 22.148, 3.98751;
-11.8022, 22.5945, 1.47664;
-8.85457, 20.8696, 12.1895;
-10.131, 21.5096, 7.94287;
4.63046, 134.052, -139.576;
-10.0719, 43.1032, -79.1781;
-10.7667, 21.8667, 5.68727;
-12.6587, 38.5085, -61.6436;
3.95535, 241.725, -146.174;
-15.1097, 31.1952, -35.2305;
-14.9267, 27.8269, -22.3608;
-15.0656, 31.6803, -37.016;
-9.86649, 21.3662, 8.86292;
4.58261, 106.635, -135.457;
-13.3958, 36.9225, -55.8701;
-14.8467, 27.4234, -20.75;
-9.26049, 44.3478, -84.1828;
-9.51023, 43.9693, -82.6548;
-13.9657, 25.1136, -10.9592;
-14.4925, 34.1899, -46.0425;
-10.5672, 42.3162, -76.0544;
-11.5984, 40.5562, -69.2552;
-0.993421, 64.013, -126.478;
0.765767, 72.1493, -130.141;
-2.1096, 59.7809, -122.798;
-12.1454, 39.5104, -65.3578;
-13.062, 37.65, -58.5144;
-6.68714, 48.3172, -99.7383;
4.33504, 156.127, -142.176;
4.39741, 100.816, -134.536;
2.55245, 82.6571, -132.286;
-14.4223, 26.1384, -15.3963;
-1.22434, 63.1015, -125.766;
-4.58353, 52.82, -111.184;
-5.20508, 51.4016, -107.822;
1.17634, 74.0686, -130.953;
-7.37625, 47.2239, -95.5894;
-14.9706, 32.2558, -39.1074;
-15.1378, 29.7063, -29.6614;
-13.3868, 24.326, -7.21636;
-2.6613, 58.1303, -120.338;
-5.48993, 50.7878, -106.232;
-15.0685, 28.7501, -25.9925;
-13.7052, 36.2122, -53.3032;
0.437576, 70.5848, -129.527;
];
//skeleton lines
lines = [
93, 24;
56, 44;
0, 89;
42, 59;
7, 64;
17, 90;
62, 50;
39, 59;
48, 77;
3, 36;
13, 14;
10, 157;
20, 79;
19, 17;
43, 60;
76, 90;
157, 136;
4, 72;
79, 117;
14, 2;
7, 6;
40, 6;
62, 66;
135, 10;
49, 73;
38, 5;
61, 75;
137, 153;
78, 148;
2, 57;
38, 47;
117, 33;
61, 83;
35, 40;
9, 137;
58, 56;
153, 34;
1, 41;
9, 145;
39, 121;
82, 98;
25, 147;
25, 146;
23, 34;
8, 99;
23, 146;
60, 91;
149, 54;
108, 27;
156, 127;
139, 120;
112, 132;
109, 110;
150, 111;
124, 122;
151, 28;
150, 124;
155, 123;
151, 155;
29, 144;
128, 123;
114, 85;
30, 85;
114, 113;
95, 115;
115, 31;
116, 125;
95, 125;
31, 86;
55, 86;
87, 96;
88, 96;
52, 53;
1, 37;
58, 91;
70, 47;
8, 69;
5, 64;
53, 69;
126, 22;
15, 50;
45, 16;
65, 63;
45, 63;
13, 37;
141, 51;
57, 35;
15, 74;
71, 74;
48, 68;
72, 68;
46, 67;
20, 4;
70, 73;
141, 100;
16, 66;
18, 12;
52, 75;
18, 65;
46, 81;
42, 43;
121, 12;
41, 71;
24, 89;
22, 103;
77, 92;
21, 97;
36, 80;
126, 92;
21, 99;
33, 67;
102, 103;
44, 83;
76, 98;
118, 133;
87, 55;
101, 3;
51, 81;
49, 100;
136, 148;
78, 11;
142, 101;
82, 93;
19, 97;
104, 140;
140, 105;
104, 149;
106, 118;
129, 107;
106, 130;
129, 130;
134, 84;
27, 84;
138, 134;
138, 120;
132, 110;
112, 111;
116, 119;
26, 105;
131, 94;
154, 147;
54, 107;
108, 133;
88, 32;
156, 109;
135, 145;
127, 139;
29, 128;
113, 119;
28, 122;
143, 80;
152, 30;
142, 102;
144, 94;
131, 152;
143, 11;
26, 154;
];
答案 0 :(得分:0)
我会:
将网格划分为单独的折线
分别处理每个。因此,您需要对点pnt[]
进行重新排序,使它们处于相同的拓扑顺序(只是点序列没有line[]
结构)。
计算|pnt[i]-sliding_average(pnt[i])|
该值将为您提供与滑动平均值的距离,因此将其阈值设置为...如果您的折线太大则将其分开。
您的数据的平均滑动(平均10个点和10个之后)如下所示(红色):
由于阈值距离我使用sqrt(20)
所以这里开始检测到的单个折线的终点(黄色):
回归
#2 后,您的设置应包含单独的线段。要提高精度,请忽略角点(折线边缘附近),因为它可能包含下一个/上一个线段的点。
我选择从开始时忽略10个点,从结束时忽略10个点。我计算了内部点的平均位置。作为方向,我使用重新调整为外部端点大小的内部端点之间的差异。从那里,回归线只是平均位置+/-半方向量。
您可以选择所需线条的拟合或回归取决于您想要达到的结果属性。
计算相邻行之间的交叉点
重建网格
这里简单的 C ++ 代码(对不起,我不使用Matlab)来覆盖#1,#2,#3 的数据而没有递归细分(折线的分支)因此,如果上述说明不够,您可以看到事情是如何完成的。
//---------------------------------------------------------------------------
//skeleton vertices
double pnt[]=
{
2.06104, 318.734, -149.29,
4.2207, 212.092, -145.141,
4.23213, 200.135, -144.811,
4.16573, 95.1567, -133.954,
4.7053, 126.626, -138.59,
4.16915, 171.645, -143.646,
4.18659, 183.173, -144.185,
4.17842, 179.964, -144.008,
2.76537, 288.063, -147.215,
-1.71817, 61.155, -124.25,
-0.492168, 66.2098, -127.702,
2.07608, 79.5012, -131.886,
4.03249, 238.699, -146.141,
4.23595, 206.822, -145.001,
4.23623, 203.704, -144.908,
4.17145, 220.543, -145.415,
4.12453, 228.514, -145.761,
2.41377, 301.021, -147.804,
4.03098, 236.064, -145.985,
2.48681, 298.432, -147.685,
4.68192, 129.093, -138.873,
2.65048, 292.424, -147.406,
4.54555, 104.737, -135.116,
-4.23707, 53.6538, -113,
1.93508, 317.106, -148.755,
-4.98045, 51.9036, -109.052,
-5.87157, 49.9703, -104.104,
-11.2433, 41.1865, -71.6569,
-15.1283, 30.7528, -33.5845,
-14.6647, 26.7291, -17.9213,
-13.1176, 23.9812, -5.55431,
-8.27057, 20.6161, 13.9826,
-4.49387, 19.0295, 25.4537,
4.5645, 139.344, -140.275,
-3.3737, 56.0265, -117.133,
4.21667, 192.056, -144.576,
3.99948, 93.2911, -133.447,
4.22894, 209.986, -145.081,
4.17824, 167.633, -143.406,
3.94993, 243.303, -146.26,
4.20391, 188.412, -144.431,
4.20673, 214.944, -145.239,
3.82056, 248.85, -146.382,
3.75634, 252.761, -146.523,
3.46093, 268.466, -147.033,
4.11554, 230.181, -145.836,
4.44799, 147.962, -141.303,
4.205, 165.551, -143.138,
4.7514, 117.603, -137.34,
4.25931, 161.613, -142.739,
4.15939, 222.571, -145.502,
4.38497, 152.519, -141.797,
3.12906, 279.268, -147.181,
3.05571, 282.333, -147.279,
-8.35374, 45.7208, -89.6802,
-6.43016, 19.7295, 20.0489,
3.51218, 265.85, -146.95,
4.22735, 196.569, -144.716,
3.60114, 261.275, -146.806,
3.87527, 245.264, -146.243,
3.70115, 255.948, -146.633,
3.33032, 273.433, -147.142,
4.14712, 224.649, -145.592,
4.11102, 231.178, -145.882,
4.17545, 177.258, -143.86,
4.07209, 234.491, -145.985,
4.13698, 226.37, -145.667,
4.50243, 144.003, -140.851,
4.74996, 120.215, -137.661,
3.00397, 283.765, -147.29,
4.22263, 164.279, -143.008,
4.19542, 216.684, -145.284,
4.74419, 122.387, -138.079,
4.24362, 162.754, -142.854,
4.1921, 217.204, -145.299,
3.1988, 276.954, -147.144,
2.24673, 307.266, -148.14,
4.70408, 113.726, -136.704,
1.55558, 75.9859, -131.562,
4.66136, 131.166, -139.157,
3.69856, 90.4963, -133.113,
4.42481, 149.643, -141.489,
2.02224, 313.586, -148.445,
3.39344, 270.742, -147.067,
-11.4507, 40.824, -70.2682,
-12.6325, 23.3651, -2.57932,
-7.10479, 20.0528, 17.8335,
-5.64725, 19.4808, 22.078,
-4.64392, 19.0822, 25.039,
2.02817, 318.148, -149.125,
2.33964, 303.688, -147.933,
3.66401, 257.998, -146.701,
4.63971, 109.538, -135.974,
1.92836, 315.331, -148.48,
-14.1808, 25.5312, -12.8091,
-9.41149, 21.1265, 10.4194,
-4.95978, 19.1884, 24.1908,
2.59159, 294.625, -147.508,
2.13575, 310.184, -148.256,
2.70921, 290.146, -147.303,
4.27225, 160.675, -142.644,
4.26101, 97.2627, -134.029,
4.48821, 103.188, -134.891,
4.49926, 103.485, -134.935,
-7.047, 47.7435, -97.5736,
-6.3594, 48.9598, -101.483,
-9.77383, 43.5659, -81.0321,
-8.9763, 44.7772, -85.911,
-10.8234, 41.8961, -74.4074,
-13.9937, 35.5167, -50.7962,
-14.3038, 34.7247, -47.9571,
-14.8257, 32.9699, -41.6747,
-14.6745, 33.5497, -43.7501,
-11.2159, 22.148, 3.98751,
-11.8022, 22.5945, 1.47664,
-8.85457, 20.8696, 12.1895,
-10.131, 21.5096, 7.94287,
4.63046, 134.052, -139.576,
-10.0719, 43.1032, -79.1781,
-10.7667, 21.8667, 5.68727,
-12.6587, 38.5085, -61.6436,
3.95535, 241.725, -146.174,
-15.1097, 31.1952, -35.2305,
-14.9267, 27.8269, -22.3608,
-15.0656, 31.6803, -37.016,
-9.86649, 21.3662, 8.86292,
4.58261, 106.635, -135.457,
-13.3958, 36.9225, -55.8701,
-14.8467, 27.4234, -20.75,
-9.26049, 44.3478, -84.1828,
-9.51023, 43.9693, -82.6548,
-13.9657, 25.1136, -10.9592,
-14.4925, 34.1899, -46.0425,
-10.5672, 42.3162, -76.0544,
-11.5984, 40.5562, -69.2552,
-0.993421, 64.013, -126.478,
0.765767, 72.1493, -130.141,
-2.1096, 59.7809, -122.798,
-12.1454, 39.5104, -65.3578,
-13.062, 37.65, -58.5144,
-6.68714, 48.3172, -99.7383,
4.33504, 156.127, -142.176,
4.39741, 100.816, -134.536,
2.55245, 82.6571, -132.286,
-14.4223, 26.1384, -15.3963,
-1.22434, 63.1015, -125.766,
-4.58353, 52.82, -111.184,
-5.20508, 51.4016, -107.822,
1.17634, 74.0686, -130.953,
-7.37625, 47.2239, -95.5894,
-14.9706, 32.2558, -39.1074,
-15.1378, 29.7063, -29.6614,
-13.3868, 24.326, -7.21636,
-2.6613, 58.1303, -120.338,
-5.48993, 50.7878, -106.232,
-15.0685, 28.7501, -25.9925,
-13.7052, 36.2122, -53.3032,
0.437576, 70.5848, -129.527,
};
const int pnts3=sizeof(pnt)/sizeof(pnt[1]); // number of points * 3
const int pnts=pnts3/3; // number of points
//skeleton lines
int lin[]=
{
93, 24,
56, 44,
0, 89,
42, 59,
7, 64,
17, 90,
62, 50,
39, 59,
48, 77,
3, 36,
13, 14,
10, 157,
20, 79,
19, 17,
43, 60,
76, 90,
157, 136,
4, 72,
79, 117,
14, 2,
7, 6,
40, 6,
62, 66,
135, 10,
49, 73,
38, 5,
61, 75,
137, 153,
78, 148,
2, 57,
38, 47,
117, 33,
61, 83,
35, 40,
9, 137,
58, 56,
153, 34,
1, 41,
9, 145,
39, 121,
82, 98,
25, 147,
25, 146,
23, 34,
8, 99,
23, 146,
60, 91,
149, 54,
108, 27,
156, 127,
139, 120,
112, 132,
109, 110,
150, 111,
124, 122,
151, 28,
150, 124,
155, 123,
151, 155,
29, 144,
128, 123,
114, 85,
30, 85,
114, 113,
95, 115,
115, 31,
116, 125,
95, 125,
31, 86,
55, 86,
87, 96,
88, 96,
52, 53,
1, 37,
58, 91,
70, 47,
8, 69,
5, 64,
53, 69,
126, 22,
15, 50,
45, 16,
65, 63,
45, 63,
13, 37,
141, 51,
57, 35,
15, 74,
71, 74,
48, 68,
72, 68,
46, 67,
20, 4,
70, 73,
141, 100,
16, 66,
18, 12,
52, 75,
18, 65,
46, 81,
42, 43,
121, 12,
41, 71,
24, 89,
22, 103,
77, 92,
21, 97,
36, 80,
126, 92,
21, 99,
33, 67,
102, 103,
44, 83,
76, 98,
118, 133,
87, 55,
101, 3,
51, 81,
49, 100,
136, 148,
78, 11,
142, 101,
82, 93,
19, 97,
104, 140,
140, 105,
104, 149,
106, 118,
129, 107,
106, 130,
129, 130,
134, 84,
27, 84,
138, 134,
138, 120,
132, 110,
112, 111,
116, 119,
26, 105,
131, 94,
154, 147,
54, 107,
108, 133,
88, 32,
156, 109,
135, 145,
127, 139,
29, 128,
113, 119,
28, 122,
143, 80,
152, 30,
142, 102,
144, 94,
131, 152,
143, 11,
26, 154,
};
const int lins2=sizeof(lin)/sizeof(lin[1]); // number of lines * 2
const int lins=lins2/2; // number of lines
//---------------------------------------------------------------------------
int pol[pnts],pols=0; // polyline
double avg[pnts3]; // sliding average
//---------------------------------------------------------------------------
const int _mesh=100;
double mesh[_mesh*3];
int meshs=0,meshs3=0;
//---------------------------------------------------------------------------
void compute()
{
int i,j,e,n,i0,i1;
int his[pnts];
int used[lins];
double x,y,z,w,rr,ll;
//--- compute polyline pol[pols] ----------------------------------------
// histogram of point usagge
for (i=0;i<pnts;i++) his[i]=0;
for (i=0;i<lins2;i++) his[lin[i]]++;
// clear tables
for (i=0;i<pnts;i++) pol[i]=-1; pols=0;
for (i=0;i<lins;i++) used[i]=0;
// find start point (his[i]!=2)
for (e=1,i=0;i<pnts;i++)
if ((his[i])&&(his[i]!=2))
{ e=0; break; }
if (e) return; // stop if none found
// add start point to polyline
pol[pols]=i; pols++;
// process polyline
for (e=1;e;)
for (e=0,j=0;j<lins;j++)
if (!used[j]) // ignore used lines
{
// is point i in line j ?
if (lin[j+j+0]==i) i=lin[j+j+1];
else if (lin[j+j+1]==i) i=lin[j+j+0];
else continue;
// add next point to polyline
pol[pols]=i; pols++;
used[j]=1;
if (his[i]==2) e=1; // loop if not end of polyline
break;
}
//--- compute sliding average -------------------------------------------
n=10; // sliding average half interval [poins]
w=1+n+n; w=1.0/w;
for (i=0;i<pols;i++)
{
e=3*pol[i];
x=pnt[e]; e++;
y=pnt[e]; e++;
z=pnt[e]; e++;
for (j=1;j<=n;j++)
{
e=i+j; if (e>=pols) e=pols-1;
e=3*pol[e];
x+=pnt[e]; e++;
y+=pnt[e]; e++;
z+=pnt[e]; e++;
e=i-j; if (e<0) e=0;
e=3*pol[e];
x+=pnt[e]; e++;
y+=pnt[e]; e++;
z+=pnt[e]; e++;
}
e=3*i;
avg[e]=x*w; e++;
avg[e]=y*w; e++;
avg[e]=z*w; e++;
}
//--- regress lines -----------------------------------------------------
meshs=0; meshs3=0;
ll=20.0;
for (e=0,i=0;i<pols;i++)
{
// distance to sliding average
j=3*pol[i];
x=pnt[j]; j++;
y=pnt[j]; j++;
z=pnt[j]; j++;
j=3*i;
x-=avg[j]; j++; x*=x;
y-=avg[j]; j++; y*=y;
z-=avg[j]; j++; z*=z;
rr=x+y+z;
if ((e==0)&&(rr<=ll)){ i0=i; e++; }// find start point
else if ((e==1)&&(rr> ll)) // find end point
{
i1=i-1; e=0; if (i0==i1) continue;
// regress line from pol[i0..i1]
int j0,j1;
double dx,dy,dz;
// ignore n edge points
n=10; while ((i1-i0)<(n<<2)) n--;
j0=i0+n;
j1=i1-n;
// direction
j=3*pol[j1];
dx=pnt[j]; j++;
dy=pnt[j]; j++;
dz=pnt[j]; j++;
j=3*pol[j0];
dx-=pnt[j]; j++;
dy-=pnt[j]; j++;
dz-=pnt[j]; j++;
// original line size
j=3*pol[i1];
x=pnt[j]; j++;
y=pnt[j]; j++;
z=pnt[j]; j++;
j=3*pol[i0];
x-=pnt[j]; j++;
y-=pnt[j]; j++;
z-=pnt[j]; j++;
// rescale direction to match original half size
rr=sqrt((x*x)+(y*y)+(z*z));
rr=divide(rr,sqrt((dx*dx)+(dy*dy)+(dz*dz)));
rr*=0.5;
dx*=rr;
dy*=rr;
dz*=rr;
// avg position
for (x=y=z=0.0,n=0,i=j0;i<=j1;i++)
{
j=3*pol[i];
x+=pnt[j]; j++;
y+=pnt[j]; j++;
z+=pnt[j]; j++;
n++;
}
x/=n;
y/=n;
z/=n;
// line is avg+/-half direction
mesh[meshs3]=x-dx; meshs3++; meshs++;
mesh[meshs3]=y-dy; meshs3++;
mesh[meshs3]=z-dz; meshs3++;
mesh[meshs3]=x+dx; meshs3++; meshs++;
mesh[meshs3]=y+dy; meshs3++;
mesh[meshs3]=z+dz; meshs3++;
// restore main loop
i=i1+1; e=0;
}
}
i=0;
}
//---------------------------------------------------------------------------
mesh[meshs3]
包含生成折线的 3D 点坐标(每行2个点)meshs
是点数num_of_lines=meshs/2