@@ -16,7 +16,8 @@ pub struct Object {
1616 velocity_y : f64 ,
1717 radius : f64 ,
1818 mass : f64 ,
19- restitution_coef : f64
19+ restitution_coef : f64 ,
20+ is_freeze : bool
2021}
2122
2223#[ derive( Clone , Serialize , Deserialize ) ]
@@ -89,10 +90,11 @@ impl World {
8990 pub fn add_object (
9091 & mut self , pos_x : f64 , pos_y : f64 ,
9192 velocity_x : f64 , velocity_y : f64 ,
92- radius : f64 , mass : f64 , restitution_coef : f64
93+ radius : f64 , mass : f64 , restitution_coef : f64 ,
94+ is_freeze : bool
9395 ) {
9496 self . objects . push (
95- Object { pos_x, pos_y, velocity_x, velocity_y, radius, mass, restitution_coef} ) ;
97+ Object { pos_x, pos_y, velocity_x, velocity_y, radius, mass, restitution_coef, is_freeze } ) ;
9698 }
9799
98100 pub fn get_world ( & self ) -> JsValue {
@@ -142,32 +144,63 @@ impl World {
142144 let overlap = obj. radius + obj_. radius - distance;
143145
144146 if overlap > 0. {
145- let correction_ratio = overlap / distance;
146- obj. pos_x -= delta_x * correction_ratio;
147- obj. pos_y -= delta_y * correction_ratio;
148- obj_. pos_x += delta_x * correction_ratio;
149- obj_. pos_y += delta_y * correction_ratio;
147+ let a = ( obj_. pos_y - obj. pos_y ) . atan2 ( obj_. pos_x - obj. pos_x ) ;
148+ if ( obj. is_freeze ) {
149+ obj_. pos_x += overlap * a. cos ( ) ;
150+ obj_. pos_y += overlap * a. sin ( ) ;
151+ }
152+ else if ( obj_. is_freeze ) {
153+ obj. pos_x -= overlap * a. cos ( ) ;
154+ obj. pos_y -= overlap * a. sin ( ) ;
155+ } else {
156+ let correction_ratio = overlap / distance;
157+ obj. pos_x -= delta_x * correction_ratio;
158+ obj. pos_y -= delta_y * correction_ratio;
159+ obj_. pos_x += delta_x * correction_ratio;
160+ obj_. pos_y += delta_y * correction_ratio;
161+ }
162+
150163
151164 let relative_velocity_x = obj_. velocity_x - obj. velocity_x ;
152165 let relative_velocity_y = obj_. velocity_y - obj. velocity_y ;
153166
154167 let restitution_coef = obj. restitution_coef . max ( obj_. restitution_coef ) ;
155-
168+
156169 let dot_product = delta_x * relative_velocity_x + delta_y * relative_velocity_y;
157- let impulse = ( 2. * dot_product) / ( distance * ( obj. mass + obj_. mass ) ) ;
158-
159- obj. velocity_x += ( impulse * obj_. mass * delta_x * restitution_coef) / distance;
160- obj. velocity_y += ( impulse * obj_. mass * delta_y * restitution_coef) / distance;
161-
162- obj_. velocity_x -= ( impulse * obj. mass * delta_x * restitution_coef) / distance;
163- obj_. velocity_y -= ( impulse * obj. mass * delta_y * restitution_coef) / distance;
170+
171+ if ( obj. is_freeze ) {
172+ let impulse = ( 2. * dot_product) / ( distance * ( obj_. mass + obj_. mass ) ) ;
173+ let bounce_x = ( impulse * obj_. mass * delta_x) / distance + restitution_coef * ( ( impulse * obj_. mass * delta_x) / distance) ;
174+ let bounce_y = ( impulse * obj_. mass * delta_y) / distance + restitution_coef * ( ( impulse * obj_. mass * delta_y) / distance) ;
175+
176+ obj_. velocity_x -= bounce_x;
177+ obj_. velocity_y -= bounce_y;
178+ }
179+ else if ( obj_. is_freeze ) {
180+ let impulse = ( 2. * dot_product) / ( distance * ( obj. mass + obj. mass ) ) ;
181+ let bounce_x = ( impulse * obj. mass * delta_x) / distance + restitution_coef * ( ( impulse * obj. mass * delta_x) / distance) ;
182+ let bounce_y = ( impulse * obj. mass * delta_y) / distance +restitution_coef * ( ( impulse * obj. mass * delta_y) / distance) ;
183+ obj. velocity_x += bounce_x;
184+ obj. velocity_y += bounce_y;
185+ }
186+ else {
187+ let impulse = ( 2. * dot_product) / ( distance * ( obj. mass + obj_. mass ) ) ;
188+
189+ obj. velocity_x += ( impulse * obj_. mass * delta_x * restitution_coef) / distance;
190+ obj. velocity_y += ( impulse * obj_. mass * delta_y * restitution_coef) / distance;
191+
192+ obj_. velocity_x -= ( impulse * obj. mass * delta_x * restitution_coef) / distance;
193+ obj_. velocity_y -= ( impulse * obj. mass * delta_y * restitution_coef) / distance;
194+ }
164195 }
165196 }
166197
167198 // position
168199 for obj in self . objects . iter_mut ( ) {
169- obj. pos_x += obj. velocity_x * elapsed_time;
170- obj. pos_y += obj. velocity_y * elapsed_time;
200+ if ( !obj. is_freeze ) {
201+ obj. pos_x += obj. velocity_x * elapsed_time;
202+ obj. pos_y += obj. velocity_y * elapsed_time;
203+ }
171204 }
172205 }
173206}
0 commit comments