source: main/trunk/model-sites-dev/von-sparql/js/paper/examples/Paperjs.org/MetaBalls.html@ 28914

Last change on this file since 28914 was 28914, checked in by ak19, 10 years ago

Supporting javascript libraries and bespoke code written by Steffan to support the von-sparql user interface

File size: 4.1 KB
Line 
1<!DOCTYPE html>
2<html>
3<head>
4 <meta charset="UTF-8">
5 <title>Meta Balls</title>
6 <link rel="stylesheet" href="../css/style.css">
7 <script type="text/javascript" src="../../dist/paper.js"></script>
8 <script type="text/paperscript" canvas="canvas">
9 // Ported from original Metaball script by SATO Hiroyuki
10 // http://park12.wakwak.com/~shp/lc/et/en_aics_script.html
11 project.currentStyle = {
12 fillColor: 'black'
13 };
14
15 var ballPositions = [[255, 129], [610, 73], [486, 363],
16 [117, 459], [484, 726], [843, 306], [789, 615], [1049, 82],
17 [1292, 428], [1117, 733], [1352, 86], [92, 798]];
18
19 var handle_len_rate = 2.4;
20 var circlePaths = [];
21 var radius = 50;
22 for (var i = 0, l = ballPositions.length; i < l; i++) {
23 var circlePath = new Path.Circle({
24 center: ballPositions[i],
25 radius: 50
26 });
27 circlePaths.push(circlePath);
28 }
29
30 var largeCircle = new Path.Circle({
31 center: [676, 433],
32 radius: 100
33 });
34 circlePaths.push(largeCircle);
35
36 function onMouseMove(event) {
37 largeCircle.position = event.point;
38 generateConnections(circlePaths);
39 }
40
41 var connections = new Group();
42 function generateConnections(paths) {
43 // Remove the last connection paths:
44 connections.children = [];
45
46 for (var i = 0, l = paths.length; i < l; i++) {
47 for (var j = i - 1; j >= 0; j--) {
48 var path = metaball(paths[i], paths[j], 0.5, handle_len_rate, 300);
49 if (path) {
50 connections.appendTop(path);
51 path.removeOnMove();
52 }
53 }
54 }
55 }
56
57 generateConnections(circlePaths);
58
59 // ---------------------------------------------
60 function metaball(ball1, ball2, v, handle_len_rate, maxDistance) {
61 var center1 = ball1.position;
62 var center2 = ball2.position;
63 var radius1 = ball1.bounds.width / 2;
64 var radius2 = ball2.bounds.width / 2;
65 var pi2 = Math.PI / 2;
66 var d = center1.getDistance(center2);
67 var u1, u2;
68
69 if (radius1 == 0 || radius2 == 0)
70 return;
71
72 if (d > maxDistance || d <= Math.abs(radius1 - radius2)) {
73 return;
74 } else if (d < radius1 + radius2) { // case circles are overlapping
75 u1 = Math.acos((radius1 * radius1 + d * d - radius2 * radius2) /
76 (2 * radius1 * d));
77 u2 = Math.acos((radius2 * radius2 + d * d - radius1 * radius1) /
78 (2 * radius2 * d));
79 } else {
80 u1 = 0;
81 u2 = 0;
82 }
83
84 var angle1 = (center2 - center1).getAngleInRadians();
85 var angle2 = Math.acos((radius1 - radius2) / d);
86 var angle1a = angle1 + u1 + (angle2 - u1) * v;
87 var angle1b = angle1 - u1 - (angle2 - u1) * v;
88 var angle2a = angle1 + Math.PI - u2 - (Math.PI - u2 - angle2) * v;
89 var angle2b = angle1 - Math.PI + u2 + (Math.PI - u2 - angle2) * v;
90 var p1a = center1 + getVector(angle1a, radius1);
91 var p1b = center1 + getVector(angle1b, radius1);
92 var p2a = center2 + getVector(angle2a, radius2);
93 var p2b = center2 + getVector(angle2b, radius2);
94
95 // define handle length by the distance between
96 // both ends of the curve to draw
97 var totalRadius = (radius1 + radius2);
98 var d2 = Math.min(v * handle_len_rate, (p1a - p2a).length / totalRadius);
99
100 // case circles are overlapping:
101 d2 *= Math.min(1, d * 2 / (radius1 + radius2));
102
103 radius1 *= d2;
104 radius2 *= d2;
105
106 var path = new Path({
107 segments: [p1a, p2a, p2b, p1b],
108 style: ball1.style,
109 closed: true
110 });
111 var segments = path.segments;
112 segments[0].handleOut = getVector(angle1a - pi2, radius1);
113 segments[1].handleIn = getVector(angle2a + pi2, radius2);
114 segments[2].handleOut = getVector(angle2b - pi2, radius2);
115 segments[3].handleIn = getVector(angle1b + pi2, radius1);
116 return path;
117 }
118
119 // ------------------------------------------------
120 function getVector(radians, length) {
121 return new Point({
122 // Convert radians to degrees:
123 angle: radians * 180 / Math.PI,
124 length: length
125 });
126 }
127 </script>
128</head>
129<body>
130 <canvas id="canvas" resize></canvas>
131</body>
132</html>
Note: See TracBrowser for help on using the repository browser.