Files: 4811bd9f673ac20d7ecf3d72f06c219cef743535 / triangulate.js
4467 bytesRaw
1 | function toDegrees (rad) { |
2 | return rad*180/Math.PI |
3 | } |
4 | |
5 | function dist (a, b) { |
6 | return Math.sqrt(Math.pow(a[0] - b[0], 2) + Math.pow(a[1] - b[1], 2)) |
7 | } |
8 | |
9 | //given two 2d points and two distances, return a point. |
10 | //this has some floating point errors, probably better ways |
11 | //to do with without sin/cos/tan? |
12 | function triangulate(a, da, b, db) { |
13 | var c = dist(a, b) |
14 | var cos = (da*da + c*c - db*db)/(2*da*c) |
15 | var angle = Math.acos(cos) |
16 | var cos2 = (db*db + c*c - da*da)/(2*db*c) |
17 | var angle2 = Math.acos(cos2) |
18 | var _angle = Math.atan( (a[1]-b[1]) / (a[0]-b[0]) ) |
19 | var _angle2 = Math.atan( (b[1]-a[1]) / (b[0]-a[0]) ) |
20 | |
21 | // console.log('ANGLE', toDegrees(angle), toDegrees(_angle), |
22 | // Math.sin(angle+_angle), |
23 | // Math.cos(angle+_angle), |
24 | // da |
25 | // |
26 | // ) |
27 | console.log('angle', toDegrees(_angle), toDegrees(_angle2)) |
28 | var x = [ |
29 | a[0] + Math.sin(angle+_angle)*da, |
30 | a[1] + Math.cos(angle+_angle)*da |
31 | ] |
32 | var x2 = [ |
33 | b[0] + Math.sin(angle2+_angle2)*db, |
34 | b[1] + Math.cos(angle2+_angle2)*db |
35 | ] |
36 | console.log(x, x2) |
37 | |
38 | |
39 | console.log('dist a', da - dist(a, x)) |
40 | console.log('dist b', db - dist(b, x)) |
41 | if(angle2 < angle) return x2 |
42 | return x |
43 | } |
44 | |
45 | //console.log(dist([0,0], [1,-1])) |
46 | |
47 | //console.log(triangulate([0,0], 1, [1,1], 1)) |
48 | //console.log(triangulate([0,0], 5, [3,0], 4)) |
49 | |
50 | //should be [-1, 1], or [1, 1] |
51 | console.log('T', triangulate([0,0], 1.414, [0,1], 1)) |
52 | //should be [-1, 0] or [1, 0] |
53 | console.log('T', triangulate([0,0], 1, [0,1], 1.414)) |
54 | |
55 | //return |
56 | |
57 | exports.triangulate = triangulate |
58 | |
59 | exports.develop = function (polygon, developed) { |
60 | var a, b |
61 | //given |
62 | //developed is a map of vertices already layed out |
63 | //first find a known edge: two vertices already developed. |
64 | for(var k in polygon.vertices) { |
65 | var v = polygon.vertices[k] |
66 | if(!a && developed[vertexId(v)]) |
67 | a = v |
68 | else if(!b && developed[vertexId(v)]) |
69 | b = v |
70 | } |
71 | if(!a && !b) throw new Error('could not develop polygon, do not have two matching vertices') |
72 | |
73 | //calculate distance between a and b |
74 | // console.log(a, b) |
75 | var d = a.pos.distanceTo(b.pos) |
76 | var vertices = [] |
77 | for(var k in polygon.vertices) { |
78 | var v = polygon.vertices[k] |
79 | if(developed[vertexId(v)]) //either a or b |
80 | vertices.push(developed[vertexId(v)]) |
81 | else { |
82 | var _v = triangulate(developed[vertexId(a)], a.pos.distanceTo(v.pos), developed[vertexId(b)], b.pos.distanceTo(v.pos)) |
83 | console.log("VERTICE", _v, a.pos.distanceTo(v.pos), b.pos.distanceTo(v.pos)) |
84 | vertices.push(_v) |
85 | if(!developed[vertexId(v)]) |
86 | developed[vertexId(v)] = _v |
87 | } |
88 | } |
89 | return vertices |
90 | } |
91 | |
92 | var CSG = require('@jscad/csg').CSG |
93 | |
94 | var square = {vertices: [ |
95 | new CSG.Vector3D(0, 0, 0), |
96 | new CSG.Vector3D(0, 3, 0), |
97 | new CSG.Vector3D(4, 3, 0), |
98 | // new CSG.Vector3D(10, 0, 0) |
99 | ].map(function (e, i) { |
100 | e = new CSG.Vertex(e) |
101 | e.tag = i+1 |
102 | return e |
103 | })} |
104 | |
105 | //console.log(exports.develop(square, {1: [0,2], 2:[0, 5]})) |
106 | |
107 | var c = CSG.cube({center: [0,0,0], size: 2}) |
108 | console.log(c) |
109 | var d = {} //: [0,0], 2:[2, 0]} |
110 | d[vertexId(c.polygons[0].vertices[0])] = [0,0] |
111 | d[vertexId(c.polygons[0].vertices[1])] = [0,2] |
112 | |
113 | console.log(d) |
114 | |
115 | function vertexId(e) { |
116 | e = e.pos || e |
117 | return [e.x,e.y,e.z].join(',') |
118 | } |
119 | |
120 | function sideId (poly) { |
121 | return poly.vertices.map(vertexId).join(':') |
122 | } |
123 | |
124 | function findUndevelopedPoly(shape, sides, developed) { |
125 | for(var i = 0; i < shape.polygons.length; i++) { |
126 | var poly = shape.polygons[i] |
127 | if(!sides[sideId(poly)]) { |
128 | var n = 0 |
129 | for(var j = 0; j < poly.vertices.length; j++) { |
130 | if(developed[vertexId(poly.vertices[j])]) n++ |
131 | } |
132 | |
133 | console.log(n) |
134 | if(n >= 2) return poly |
135 | } |
136 | } |
137 | // throw new Error('could not find a polygon to develop') |
138 | } |
139 | |
140 | |
141 | var sides = {} |
142 | var side = findUndevelopedPoly(c, sides, d) |
143 | while(side) { |
144 | sides[sideId(side)] = exports.develop(side, d) |
145 | // console.log('so far', sides, d) |
146 | side = findUndevelopedPoly(c, sides, d) |
147 | } |
148 | |
149 | console.log('SIDES', sides, d) |
150 | |
151 | //return |
152 | module.exports = function (_) { |
153 | //return c |
154 | sd = Object.keys(sides).map(function (k) { |
155 | var side = sides[k].map(function (v) { |
156 | console.log(v) |
157 | return v |
158 | // return new _.CSG.Vector2D(v[0], v[1]) |
159 | }) |
160 | return _.CSG |
161 | .Polygon.createFromPoints(side, null, CSG.Plane.fromPoints.apply(null, side.slice().reverse())) |
162 | .extrude(new CSG.Vector3D(0,0,1)) |
163 | })//.slice(0, 1) |
164 | console.log('SIDES', sd) |
165 | return sd[0] |
166 | // .reduce(function (a, b) { |
167 | // console.log('union', a) |
168 | // return a.union(b) |
169 | // }) |
170 | } |
171 | |
172 | |
173 | |
174 | |
175 | |
176 | |
177 | |
178 | |
179 |
Built with git-ssb-web