i got a skeleton of mesh, that is needed to determinate the orientation of the mesh, so i can position it correctly in 3d space automatically.
I don't really get how to get best fit of lines, so i can position it afterwards automatically from the set of points.
Below is the example of how it around how it should look and also set of sample data.
![](https://www.manongdao.com/static/images/pcload.jpg)
//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;
];
I would:
divide the mesh into separate polylines
and process each separately. So you need to reorder the points pnt[]
so they are in the same topological order (just sequence of points no line[]
structure).
compute |pnt[i]-sliding_average(pnt[i])|
the value will give you distance from sliding average so threshold it ... if too big divide your polyline.
Sliding average (averaging 10 points before and 10 after) for your data looks like this (red):
![](https://www.manongdao.com/static/images/pcload.jpg)
As threshold distance I used sqrt(20)
so here start end endpoints of the individual polylines detected (yellow):
![](https://www.manongdao.com/static/images/pcload.jpg)
regress lines
after #2 your set should contain individual line segments. To improve precision ignore corner points (near edges of polyline) as it could contain points from next/previous line segment.
![](https://www.manongdao.com/static/images/pcload.jpg)
I choose to ignore 10 points from beginning and 10 from end. I computed avg position of the inside points. As direction I use difference between inside endpoints rescaled to size of outside endpoints. From that the regressed line is just avg position +/- half direction vector.
You can chose what ever fitting or regression of lines you want depends on the properties of result you want to achieve.
compute intersection between neighboring lines
reconstruct mesh
Here simple C++ code (sorry I do not use Matlab) for your data covering #1,#2,#3 without the recursive subdivision (branching of polyline) so you can see how the things are done in case the above description is not enough.
//---------------------------------------------------------------------------
//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;
}
//---------------------------------------------------------------------------
the mesh[meshs3]
holds 3D points coordinates of the resulting polyline (2 points per line) meshs
is the number of points so num_of_lines=meshs/2