1+ // / @func get_edge_position(instance, bounding_box)
2+ // / @desc Get the closest position of ans instance to the edge of rectangle
3+ // / @param {Instance} instance
4+ // / @param {Rectangle} bounding_box
5+ function get_edge_position (_instance, _bounding_box) {
6+ var _pos = new Vector2 (_instance.x , _instance.y );
7+ var _bb_mid = new Vector2 (
8+ _bounding_box.left + _bounding_box.width ()/2 ,
9+ _bounding_box.top + _bounding_box.height ()/2
10+ );
11+
12+ var _cur_t1 = -1 ;
13+ var _cur_dist;
14+ var _edge = new Vector2 (0 , 0 );
15+ var _closest_dist = 1000000 ;
16+ var _closest_pos = new Vector3 (-1 , -1 , -1 );
17+
18+ if (!collision_rectangle (_bounding_box.left , _bounding_box.top ,
19+ _bounding_box.right , _bounding_box.bottom ,
20+ _instance, false , false )) {
21+
22+ // left
23+ _cur_t1 = ray_line_intersect (_bb_mid, _pos, _bounding_box.left_edge ());
24+
25+ if (_cur_t1 != -1 ) {
26+ _edge.x = _bb_mid.x + lengthdir_x (_cur_t1, point_direction (_bb_mid.x , _bb_mid.y , _pos.x , _pos.y ));
27+ _edge.y = _bb_mid.y + lengthdir_y (_cur_t1, point_direction (_bb_mid.x , _bb_mid.y , _pos.x , _pos.y ));
28+ _cur_dist = point_distance (_pos.x , _pos.y , _edge.x , _edge.y );
29+
30+ if (_cur_dist < _closest_dist) {
31+ _closest_dist = _cur_dist;
32+ _closest_pos.x = _edge.x ;
33+ _closest_pos.y = _edge.y ;
34+ _closest_pos.z = point_direction (_bb_mid.x , _bb_mid.y , _pos.x , _pos.y );
35+ }
36+ }
37+
38+ // right
39+ _cur_t1 = ray_line_intersect (_bb_mid, _pos, _bounding_box.right_edge ());
40+
41+ if (_cur_t1 != -1 ) {
42+ _edge.x = _bb_mid.x + lengthdir_x (_cur_t1,point_direction (_bb_mid.x , _bb_mid.y , _pos.x , _pos.y ));
43+ _edge.y = _bb_mid.y + lengthdir_y (_cur_t1,point_direction (_bb_mid.x , _bb_mid.y , _pos.x , _pos.y ));
44+ _cur_dist = point_distance (_pos.x , _pos.y , _edge.x , _edge.y );
45+
46+ if (_cur_dist < _closest_dist) {
47+ _closest_dist = _cur_dist;
48+ _closest_pos.x = _edge.x ;
49+ _closest_pos.y = _edge.y ;
50+ _closest_pos.z = point_direction (_bb_mid.x ,_bb_mid.y ,_pos.x , _pos.y );
51+ }
52+ }
53+
54+ // top
55+ _cur_t1 = ray_line_intersect (_bb_mid, _pos, _bounding_box.top_edge ());
56+
57+ if (_cur_t1 != -1 ) {
58+ _edge.x = _bb_mid.x + lengthdir_x (_cur_t1,point_direction (_bb_mid.x , _bb_mid.y , _pos.x , _pos.y ));
59+ _edge.y = _bb_mid.y + lengthdir_y (_cur_t1,point_direction (_bb_mid.x , _bb_mid.y , _pos.x , _pos.y ));
60+ _cur_dist = point_distance (_pos.x , _pos.y , _edge.x , _edge.y );
61+
62+ if (_cur_dist < _closest_dist) {
63+ _closest_dist = _cur_dist;
64+ _closest_pos.x = _edge.x ;
65+ _closest_pos.y = _edge.y ;
66+ _closest_pos.z = point_direction (_bb_mid.x ,_bb_mid.y ,_pos.x , _pos.y );
67+ }
68+ }
69+
70+ // bottom
71+ _cur_t1 = ray_line_intersect (_bb_mid, _pos, _bounding_box.bottom_edge ());
72+
73+ if (_cur_t1 != -1 ) {
74+ _edge.x = _bb_mid.x + lengthdir_x (_cur_t1,point_direction (_bb_mid.x , _bb_mid.y , _pos.x , _pos.y ));
75+ _edge.y = _bb_mid.y + lengthdir_y (_cur_t1,point_direction (_bb_mid.x , _bb_mid.y , _pos.x , _pos.y ));
76+ _cur_dist = point_distance (_pos.x , _pos.gravity_direction , _edge.x , _edge.y );
77+
78+ if (_cur_dist < _closest_dist) {
79+ _closest_dist = _cur_dist;
80+ _closest_pos.x = _edge.x ;
81+ _closest_pos.y = _edge.y ;
82+ _closest_pos.z = point_direction (_bb_mid.x ,_bb_mid.y ,_pos.x , _pos.y );
83+ }
84+ }
85+ }
86+
87+ return _closest_pos;
88+ }
89+
90+ // / @func point_which_side(A, B, P)
91+ // / @desc Returns which side of a line segment AB a point P is on
92+ // / 0 = on the line
93+ // / < 0 = below or left
94+ // / > 0 = above or right
95+ // / @param {LineSegment} line
96+ // / @param {Vector2} P
97+ function point_which_side (_line, _p) {
98+ return (_p.x - _line.a .x ) * (_line.b .y - _line.y ) - (_p.y - _line.a .y ) * (_line.b .x - _line.a .x );
99+ }
100+
101+ // / @func prune_path(path)
102+ // / @desc Removes redundant points in a Path
103+ // / @param {Path} path
104+ // / @param {Object} obstacle
105+ function prune_path (_path, _obstacle) {
106+ var _num_points = path_get_number (_path);
107+
108+ if (_num_points == 1 )
109+ return ;
110+
111+ var _cur = new Vector2 (path_get_x (_path, 0 ), path_get_y (_path, 0 ));
112+ var _next = new Vector2 (0 , 0 );
113+
114+ for (var i=1 ; i<_num_points; i++) {
115+ _next.x = path_get_x (_path, i);
116+ _next.y = path_get_y (_path, i);
117+
118+ if (!collision_line (_cur.x , _cur.y , _next.x , _next.y , _obstacle, false , true )) {
119+ if (i <_num_points-1 )
120+ path_delete_point (_path,i);
121+ }
122+
123+ else {
124+ _cur.x = _next.x ;
125+ _cur.y = _next.y ;
126+ }
127+ }
128+ }
129+
130+
131+ // / @func ray_line_intersect(origin, target, a, b)
132+ // / @desc Finds the intersection point between a ray and and a line segment
133+ // / @param {Vector2} origin
134+ // / @param {Vector2} target
135+ // / @param {LineSegement} line
136+ function ray_line_intersect (_origin, _target, _line) {
137+ var _ray_dir = point_direction (_origin.x , _origin.y , _target.x , _target.y );
138+
139+ var _v1 = new Vector2 (_origin.x - _line.a .x , _origin.y - _line.a .y );
140+ var _v2 = new Vector2 (_line.b .x - _line.a .x , _line.b .y - _line.a .y );
141+ var _v3 = new Vector2 (-lengthdir_y (1 , _ray_dir), lengthdir_x (1 , _ray_dir));
142+
143+ var _dot = dot_product (_v2.x , _v2.y , _v3.x , _v3.y );
144+
145+ if (abs (_dot) == 0 )
146+ return -1 ;
147+
148+ var _t1 = cross_product_2d (_v2, _v1) / _dot;
149+ var _t2 = dot_product (_v1.x , _v1.y , _v3.x , _v3.y ) / _dot;
150+
151+ if (_t1 >= 0 && (_t2 >= 0 && _t2 <= 1 ))
152+ return _t1;
153+
154+ return -1 ;
155+ }
156+
157+ // / @func ray_reflect(incident_dir, normal_dir)
158+ // / @desc Rr = Ri - 2 * N * (Ri . N)
159+ // / @param {real} incident_dir
160+ // / @param {real} normal_dir
161+ function ray_reflect (_incident_dir, _normal_dir) {
162+ var _ri = new Vector2 (lengthdir_x (1 , _incident_dir), lengthdir_y (1 , _incident_dir));
163+ var _n = new Vector2 (lengthdir_x (1 , _normal_dir), lengthdir_y (1 , _normal_dir));
164+
165+ var _dot = dot_product (_ri.x , _ri.y , _n.x , _n.y );
166+ var _reflect_x = _ri.x - 2 * _n.x * _dot;
167+ var _reflect_y = _ri.y - 2 * _n.y * _dot;
168+
169+ return point_direction (0 , 0 , _reflect_x, _reflect_y);
170+ }
0 commit comments