{"id":16572,"date":"2025-12-30T10:25:56","date_gmt":"2025-12-30T01:25:56","guid":{"rendered":"http:\/\/www.gisdeveloper.co.kr\/?p=16572"},"modified":"2025-12-30T10:29:30","modified_gmt":"2025-12-30T01:29:30","slug":"particle%ec%97%90-%eb%8c%80%ed%95%9c-attractor-force-%ec%a0%81%ec%9a%a9","status":"publish","type":"post","link":"http:\/\/www.gisdeveloper.co.kr\/?p=16572","title":{"rendered":"Particle\uc5d0 \ub300\ud55c Attractor Force \uc801\uc6a9"},"content":{"rendered":"<p>particle \uc2dc\ubbac\ub808\uc774\uc158\uc5d0\uc11c <bold>attractor force(\uc5b4\ud2b8\ub799\ud130 \ud798)<\/bold>\ub780, \uc785\uc790(particle)\uac00 \ud2b9\uc815 \uc9c0\uc810 \ub610\ub294 \uac1d\uccb4\ub97c \ud5a5\ud574 \ub04c\ub824\uac00\ub3c4\ub85d \ub9cc\ub4dc\ub294 \ud798\uc744 \uc758\ubbf8\ud55c\ub2e4. \uc774\ub294 \uc911\ub825, \uc790\uae30\ub825, \uc804\uae30\ub825\uacfc \uac19\uc740 \ubb3c\ub9ac\uc801 \uac1c\ub150\uc744 \ucd94\uc0c1\ud654\ud55c \uac83\uc73c\ub85c, \uc2dc\ubbac\ub808\uc774\uc158\uc5d0\uc11c \uc785\uc790\uc758 \uc9d1\ud569\uc801 \uac70\ub3d9\uc744 \uc81c\uc5b4\ud558\ub294 \ud575\uc2ec \uba54\ucee4\ub2c8\uc998 \uc911 \ud558\ub098\uc774\ub2e4.<\/p>\n<p>\uac00\uc7a5 \uae30\ubcf8\uc801\uc778 attractor force\ub294 \uc785\uc790 \uc704\uce58\uc640 \uc5b4\ud2b8\ub799\ud130 \uc704\uce58 \uc0ac\uc774\uc758 \uac70\ub9ac \ubca1\ud130\ub97c \uae30\ubc18\uc73c\ub85c \uacc4\uc0b0\ub41c\ub2e4. \uc77c\ubc18\uc801\uc73c\ub85c \ud798\uc758 \ubc29\ud5a5\uc740 (attractorPosition &#8211; particlePosition)\uc73c\ub85c \uc815\uc758\ub418\uba70, \ud06c\uae30\ub294 \uac70\ub9ac\uc758 \ud568\uc218\ub85c \uacb0\uc815\ub41c\ub2e4. \uc774\ub54c \uac70\ub9ac \uc81c\uacf1\uc5d0 \ubc18\ube44\ub840\ud558\ub294 \ud615\ud0dc(\uc608: \uc911\ub825 \uacf5\uc2dd)\ub97c \uc0ac\uc6a9\ud558\uba74, \uac00\uae4c\uc6b8\uc218\ub85d \uac15\ud558\uac8c \ub04c\ub9ac\uace0 \uba40\uc5b4\uc9c8\uc218\ub85d \uc57d\ud574\uc9c0\ub294 \uc790\uc5f0\uc2a4\ub7ec\uc6b4 \uc6c0\uc9c1\uc784\uc744 \ub9cc\ub4e4 \uc218 \uc788\ub2e4.<\/p>\n<p>\uc218\uc2dd\uc801\uc73c\ub85c\ub294 \ub2e4\uc74c\uacfc \uac19\uc740 \ud615\ud0dc\uac00 \uc790\uc8fc \uc0ac\uc6a9\ub41c\ub2e4.<\/p>\n<p><center>F = G * (dir \/ (distance^n + \u03b5))<\/center><\/p>\n<p>\uc5ec\uae30\uc11c dir\uc740 \uc815\uaddc\ud654\ub41c \ubc29\ud5a5 \ubca1\ud130, distance\ub294 \uc785\uc790\uc640 \uc5b4\ud2b8\ub799\ud130 \uc0ac\uc774\uc758 \uac70\ub9ac, n\uc740 \uac10\uc1e0 \ucc28\uc218(\ubcf4\ud1b5 1 \ub610\ub294 2), \u03b5\ub294 \uc218\uce58\uc801 \ubd88\uc548\uc815\uc744 \ubc29\uc9c0\ud558\uae30 \uc704\ud55c \uc791\uc740 \uac12\uc774\ub2e4. \uc774 \uad6c\uc870\ub294 \ubb3c\ub9ac\uc801\uc73c\ub85c \uadf8\ub7f4\ub4ef\ud558\uba74\uc11c\ub3c4 \uacc4\uc0b0 \ube44\uc6a9\uc774 \ube44\uad50\uc801 \ub0ae\ub2e4\ub294 \uc7a5\uc810\uc774 \uc788\ub2e4. <\/p>\n<p>\uc2dc\ubbac\ub808\uc774\uc158 \uad00\uc810\uc5d0\uc11c attractor force\ub294 \uc18d\ub3c4(velocity)\uc5d0 \ub204\uc801(accumulate)\ub418\ub294 \ud798\uc73c\ub85c \ucc98\ub9ac\ub41c\ub2e4. \uc989, \ub9e4 \ud504\ub808\uc784\ub9c8\ub2e4 \uc5b4\ud2b8\ub799\ud130 \ud798\uc744 \uacc4\uc0b0\ud574 \uac00\uc18d\ub3c4(acceleration)\uc5d0 \ubc18\uc601\ud558\uace0, \uc774\ub97c \uc801\ubd84\ud558\uc5ec \uc18d\ub3c4\uc640 \uc704\uce58\ub97c \uac31\uc2e0\ud55c\ub2e4. \uc774 \uacfc\uc815\uc5d0\uc11c \ud0c0\uc784\uc2a4\ud15d(delta time)\uc744 \uace0\ub824\ud558\uc9c0 \uc54a\uc73c\uba74 \ud504\ub808\uc784 \ub808\uc774\ud2b8\uc5d0 \ub530\ub77c \uc2dc\ubbac\ub808\uc774\uc158 \uacb0\uacfc\uac00 \ub2ec\ub77c\uc9c8 \uc218 \uc788\ub2e4.<\/p>\n<p>attractor\ub294 \ub2e8\uc77c \uc9c0\uc810\uc77c \uc218\ub3c4 \uc788\uace0, \uc5ec\ub7ec \uac1c\uac00 \ub3d9\uc2dc\uc5d0 \uc874\uc7ac\ud560 \uc218\ub3c4 \uc788\ub2e4. \ub2e4\uc911 \uc5b4\ud2b8\ub799\ud130 \ud658\uacbd\uc5d0\uc11c\ub294 \uac01 \uc5b4\ud2b8\ub799\ud130\ub85c\ubd80\ud130\uc758 \ud798\uc744 \ud569\uc0b0\ud558\uc5ec \ucd5c\uc885 \ud798\uc744 \uacc4\uc0b0\ud558\uba70, \uc774\ub85c \uc778\ud574 \uc785\uc790\uac00 \ud2b9\uc815 \uada4\ub3c4\uc5d0 \uba38\ubb34\ub974\uac70\ub098 \uce74\uc624\uc2a4\uc801\uc778 \uc6c0\uc9c1\uc784\uc744 \ubcf4\uc774\ub294 \ud328\ud134\uc774 \uc0dd\uc131\ub41c\ub2e4. \uc774\ub294 \ud30c\ud2f0\ud074 \uc544\ud2b8, \ub370\uc774\ud130 \uc2dc\uac01\ud654, \uc740\ud558 \uc2dc\ubbac\ub808\uc774\uc158 \ub4f1\uc5d0\uc11c \uc790\uc8fc \ud65c\uc6a9\ub41c\ub2e4.<\/p>\n<p>\uc2e4\ubb34\uc801\uc73c\ub85c\ub294 attractor force\ub97c \uadf8\ub300\ub85c \uc801\uc6a9\ud558\uba74 \uc785\uc790\uac00 \uacfc\ub3c4\ud558\uac8c \uac00\uc18d\ub418\uc5b4 \ubd88\uc548\uc815\ud574\uc9c0\ub294 \uacbd\uc6b0\uac00 \ub9ce\uae30 \ub54c\ubb38\uc5d0, force clamp(\ucd5c\ub300 \ud798 \uc81c\ud55c), damping(\uac10\uc1e0), \ub610\ub294 soft radius(\uc77c\uc815 \uac70\ub9ac \uc774\ub0b4\uc5d0\uc11c\ub9cc \uc791\ub3d9) \uac19\uc740 \ubcf4\uc815 \uae30\ubc95\uc744 \ud568\uaed8 \uc0ac\uc6a9\ud55c\ub2e4. \uc774\ub7ec\ud55c \uc81c\uc5b4 \uc7a5\uce58\ub294 \uc2dc\uac01\uc801\uc73c\ub85c \uc548\uc815\uc801\uc774\uace0 \uc608\uce21 \uac00\ub2a5\ud55c \uacb0\uacfc\ub97c \ub9cc\ub4dc\ub294 \ub370 \ud544\uc218\uc801\uc774\ub2e4.<\/p>\n<p>\uc774\uc81c \uad6c\ud604 \uad00\uc810\uc5d0\uc11c \uc124\ud3b4\ubcf4\uc790.<\/p>\n<p>\uba3c\uc800 \ud30c\ud2f0\ud074\uc744 \uac04\ub2e8\ud788 \uc815\uc758\ud574 \ubcf4\uc790.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">\r\nclass Particle {\r\n  constructor(x, y, z) {\r\n    this.position = new Vector3(x, y, z);\r\n    this.velocity = new Vector3(0, 0, 0);\r\n    this.mass = 1.0;\r\n  }\r\n}\r\n<\/pre>\n<p>\uac01 \ud30c\ud2f0\ud074\uc740 \uc704\uce58(position), \uc18d\ub3c4(velocity), \uc9c8\ub7c9(mass)\uc744 \uac00\uc9c4\ub2e4. \uc9c8\ub7c9\uc740 \ud798 \u2192 \uac00\uc18d\ub3c4 \ubcc0\ud658\uc5d0 \uc0ac\uc6a9\ub41c\ub2e4. \uc774\uc81c Attractor\uc5d0 \ub300\ud574 \uc815\uc758\ud574 \ubcf4\uc790. \uc5b4\ud2b8\ub799\ud130\ub294 \uc704\uce58\uc640 \ud798\uc758 \uc138\uae30(strength)\ub97c \uac00\uc9c4\ub2e4. \ubb3c\ub9ac\uc801\uc73c\ub85c\ub294 \u201c\uc9c8\ub7c9\uc744 \uac00\uc9c4 \uc911\uc2ec\uc810\u201d\uc5d0 \ud574\ub2f9\ud55c\ub2e4.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">\r\nclass Attractor {\r\n  constructor(x, y, z, strength = 10.0) {\r\n    this.position = new Vector3(x, y, z);\r\n    this.strength = strength;\r\n  }\r\n}\r\n<\/pre>\n<p>\ud30c\ud2f0\ud074\uc5d0 \ub300\ud55c \uc5b4\ud2b8\ub799\ud130\uac00 \ubbf8\uce58\ub294 \ud798\uc758 \uc601\ud5a5\uc744 \uacc4\uc0b0\ud558\ub294 \ud568\uc218\ub2e4. \uc785\uc790 \u2192 \uc5b4\ud2b8\ub799\ud130 \ubc29\ud5a5 \ubca1\ud130\ub97c \uad6c\ud558\uace0, \uac70\ub9ac \uae30\ubc18 \uac10\uc1e0\ub97c \uc801\uc6a9\ud55c\ub2e4. \uc5ec\uae30\uc11c\ub294 \uac70\ub9ac \uc81c\uacf1\uc5d0 \ubc18\ube44\ub840\ud558\ub294 \ud798 \ubaa8\ub378\uc744 \uc0ac\uc6a9\ud55c\ub2e4.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">\r\nfunction computeAttractorForce(particle, attractor) {\r\n  const dir = attractor.position.clone().sub(particle.position);\r\n  const distanceSq = Math.max(dir.lengthSq(), 0.0001); \/\/ \uc218\uce58 \uc548\uc815\uc131\r\n  dir.normalize();\r\n\r\n  \/\/ F = G \/ r^2\r\n  const forceMagnitude = attractor.strength \/ distanceSq;\r\n\r\n  return dir.multiplyScalar(forceMagnitude);\r\n}\r\n<\/pre>\n<p>\uc774\uc81c \uc2dc\ubbac\ub808\uc774\uc158\uc774 \uac00\ub2a5\ud558\ub2e4. \ub9e4 \ud504\ub808\uc784\ub9c8\ub2e4 \ud798 \u2192 \uac00\uc18d\ub3c4 \u2192 \uc18d\ub3c4 \u2192 \uc704\uce58 \uc21c\uc11c\ub85c \uac31\uc2e0\ud55c\ub2e4. \uc774 \uc608\uc81c\uc5d0\uc11c\ub294 \uac10\uc1e0(damping)\ub97c \ucd94\uac00\ud574 \ubc1c\uc0b0\uc744 \ubc29\uc9c0\ud55c\ub2e4.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">\r\nfunction updateParticle(particle, attractor, deltaTime) {\r\n  \/\/ 1. attractor force \uacc4\uc0b0\r\n  const force = computeAttractorForce(particle, attractor);\r\n\r\n  \/\/ 2. F = m * a \u2192 a = F \/ m\r\n  const acceleration = force.divideScalar(particle.mass);\r\n\r\n  \/\/ 3. \uc18d\ub3c4 \uac31\uc2e0\r\n  particle.velocity.add(acceleration.multiplyScalar(deltaTime));\r\n\r\n  \/\/ 4. \uac10\uc1e0 (damping)\r\n  particle.velocity.multiplyScalar(0.98);\r\n\r\n  \/\/ 5. \uc704\uce58 \uac31\uc2e0\r\n  particle.position.add(particle.velocity.clone().multiplyScalar(deltaTime));\r\n}\r\n<\/pre>\n<p>three.js\ub77c\uba74 Vector3 \ud074\ub798\uc2a4\ub97c \uc81c\uacf5\ud558\uc9c0\ub9cc three.js\uac00 \uc544\ub2cc \ud658\uacbd\uc774\ub77c\uba74 Vector3\uc5d0 \ub300\ud55c \uc815\uc758\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">\r\nclass Vector3 {\r\n  constructor(x = 0, y = 0, z = 0) {\r\n    this.x = x;\r\n    this.y = y;\r\n    this.z = z;\r\n  }\r\n\r\n  clone() {\r\n    return new Vector3(this.x, this.y, this.z);\r\n  }\r\n\r\n  add(v) {\r\n    this.x += v.x;\r\n    this.y += v.y;\r\n    this.z += v.z;\r\n    return this;\r\n  }\r\n\r\n  sub(v) {\r\n    this.x -= v.x;\r\n    this.y -= v.y;\r\n    this.z -= v.z;\r\n    return this;\r\n  }\r\n\r\n  multiplyScalar(s) {\r\n    this.x *= s;\r\n    this.y *= s;\r\n    this.z *= s;\r\n    return this;\r\n  }\r\n\r\n  divideScalar(s) {\r\n    return this.multiplyScalar(1 \/ s);\r\n  }\r\n\r\n  lengthSq() {\r\n    return this.x * this.x + this.y * this.y + this.z * this.z;\r\n  }\r\n\r\n  normalize() {\r\n    const len = Math.sqrt(this.lengthSq());\r\n    if (len > 0) this.divideScalar(len);\r\n    return this;\r\n  }\r\n}\r\n<\/pre>\n<p>\ud575\uc2ec\uc744 \uc880\ub354 \ubc18\ubcf5\ud574 \ubcf4\uba74, attractor force\ub294 \uc704\uce58 \ucc28 \ubca1\ud130 \uae30\ubc18\uc73c\ub85c \uacc4\uc0b0\ud55c\ub2e4\ub294 \uc810. \uac70\ub9ac \uae30\ubc18 \uac10\uc1e0\uac00 \uc5c6\uc73c\uba74 \uc2dc\ubbac\ub808\uc774\uc158\uc774 \uc27d\uac8c \ubd88\uc548\uc815\ud574\uc9c4\ub2e4\ub294 \uc810. damping, \ucd5c\uc18c \uac70\ub9ac \uc81c\ud55c\uc740 \uc0ac\uc2e4\uc0c1 \ud544\uc218\ub77c\ub294 \uc810. \uc774 \uad6c\uc870\ub294 CPU \ud30c\ud2f0\ud074, GPU \ud30c\ud2f0\ud074(Compute \/ GPGPU) \ubaa8\ub450\uc5d0 \ub3d9\uc77c\ud558\uac8c \uc801\uc6a9\ub41c\ub2e4\ub294 \uc810 \ub4f1\uc774\ub2e4.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>particle \uc2dc\ubbac\ub808\uc774\uc158\uc5d0\uc11c attractor force(\uc5b4\ud2b8\ub799\ud130 \ud798)\ub780, \uc785\uc790(particle)\uac00 \ud2b9\uc815 \uc9c0\uc810 \ub610\ub294 \uac1d\uccb4\ub97c \ud5a5\ud574 \ub04c\ub824\uac00\ub3c4\ub85d \ub9cc\ub4dc\ub294 \ud798\uc744 \uc758\ubbf8\ud55c\ub2e4. \uc774\ub294 \uc911\ub825, \uc790\uae30\ub825, \uc804\uae30\ub825\uacfc \uac19\uc740 \ubb3c\ub9ac\uc801 \uac1c\ub150\uc744 \ucd94\uc0c1\ud654\ud55c \uac83\uc73c\ub85c, \uc2dc\ubbac\ub808\uc774\uc158\uc5d0\uc11c \uc785\uc790\uc758 \uc9d1\ud569\uc801 \uac70\ub3d9\uc744 \uc81c\uc5b4\ud558\ub294 \ud575\uc2ec \uba54\ucee4\ub2c8\uc998 \uc911 \ud558\ub098\uc774\ub2e4. \uac00\uc7a5 \uae30\ubcf8\uc801\uc778 attractor force\ub294 \uc785\uc790 \uc704\uce58\uc640 \uc5b4\ud2b8\ub799\ud130 \uc704\uce58 \uc0ac\uc774\uc758 \uac70\ub9ac \ubca1\ud130\ub97c \uae30\ubc18\uc73c\ub85c \uacc4\uc0b0\ub41c\ub2e4. \uc77c\ubc18\uc801\uc73c\ub85c \ud798\uc758 \ubc29\ud5a5\uc740 (attractorPosition &#8211; particlePosition)\uc73c\ub85c \uc815\uc758\ub418\uba70, \ud06c\uae30\ub294 \uac70\ub9ac\uc758 &hellip; <\/p>\n<p class=\"link-more\"><a href=\"http:\/\/www.gisdeveloper.co.kr\/?p=16572\" class=\"more-link\">\ub354 \ubcf4\uae30<span class=\"screen-reader-text\"> &#8220;Particle\uc5d0 \ub300\ud55c Attractor Force \uc801\uc6a9&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[145],"tags":[],"class_list":["post-16572","post","type-post","status-publish","format-standard","hentry","category-three-js"],"_links":{"self":[{"href":"http:\/\/www.gisdeveloper.co.kr\/index.php?rest_route=\/wp\/v2\/posts\/16572","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.gisdeveloper.co.kr\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.gisdeveloper.co.kr\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.gisdeveloper.co.kr\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.gisdeveloper.co.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=16572"}],"version-history":[{"count":6,"href":"http:\/\/www.gisdeveloper.co.kr\/index.php?rest_route=\/wp\/v2\/posts\/16572\/revisions"}],"predecessor-version":[{"id":16576,"href":"http:\/\/www.gisdeveloper.co.kr\/index.php?rest_route=\/wp\/v2\/posts\/16572\/revisions\/16576"}],"wp:attachment":[{"href":"http:\/\/www.gisdeveloper.co.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=16572"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.gisdeveloper.co.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=16572"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.gisdeveloper.co.kr\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=16572"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}