<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>蜘蛛</title>
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen, projection" />
<script type="text/javascript" src="js/verlet-1.0.0.js"></script>
</head>
<body>
<canvas id="scratch" style="width: 800px; height: 500px;"></canvas>
<script type="text/javascript">
VerletJS.prototype.spider = function (origin) {
var i;
var legSeg1Stiffness = 0.99;
var legSeg2Stiffness = 0.99;
var legSeg3Stiffness = 0.99;
var legSeg4Stiffness = 0.99;
var joint1Stiffness = 1;
var joint2Stiffness = 0.4;
var joint3Stiffness = 0.9;
var bodyStiffness = 1;
var bodyJointStiffness = 1;
var composite = new this.Composite();
composite.legs = [];
composite.thorax = new Particle(origin);
composite.head = new Particle(origin.add(new Vec2(0, -5)));
composite.abdomen = new Particle(origin.add(new Vec2(0, 10)));
composite.particles.push(composite.thorax);
composite.particles.push(composite.head);
composite.particles.push(composite.abdomen);
composite.constraints.push(new DistanceConstraint(composite.head, composite.thorax, bodyStiffness));
composite.constraints.push(new DistanceConstraint(composite.abdomen, composite.thorax, bodyStiffness));
composite.constraints.push(new AngleConstraint(composite.abdomen, composite.thorax, composite.head, 0.4));
// legs
for (i = 0; i < 4; ++i) {
composite.particles.push(new Particle(composite.particles[0].pos.add(new Vec2(3, (i - 1.5) * 3))));
composite.particles.push(new Particle(composite.particles[0].pos.add(new Vec2(-3, (i - 1.5) * 3))));
var len = composite.particles.length;
composite.constraints.push(new DistanceConstraint(composite.particles[len - 2], composite.thorax, legSeg1Stiffness));
composite.constraints.push(new DistanceConstraint(composite.particles[len - 1], composite.thorax, legSeg1Stiffness));
var lenCoef = 1;
if (i == 1 || i == 2)
lenCoef = 0.7;
else if (i == 3)
lenCoef = 0.9;
composite.particles.push(new Particle(composite.particles[len - 2].pos.add((new Vec2(20, (i - 1.5) * 30)).normal().mutableScale(20 * lenCoef))));
composite.particles.push(new Particle(composite.particles[len - 1].pos.add((new Vec2(-20, (i - 1.5) * 30)).normal().mutableScale(20 * lenCoef))));
len = composite.particles.length;
composite.constraints.push(new DistanceConstraint(composite.particles[len - 4], composite.particles[len - 2], legSeg2Stiffness));
composite.constraints.push(new DistanceConstraint(composite.particles[len - 3], composite.particles[len - 1], legSeg2Stiffness));
composite.particles.push(new Particle(composite.particles[len - 2].pos.add((new Vec2(20, (i - 1.5) * 50)).normal().mutableScale(20 * lenCoef))));
composite.particles.push(new Particle(composite.particles[len - 1].pos.add((new Vec2(-20, (i - 1.5) * 50)).normal().mutableScale(20 * lenCoef))));
len = composite.particles.length;
composite.constraints.push(new DistanceConstraint(composite.particles[len - 4], composite.particles[len - 2], legSeg3Stiffness));
composite.constraints.push(new DistanceConstraint(composite.particles[len - 3], composite.particles[len - 1], legSeg3Stiffness));
var rightFoot = new Particle(composite.particles[len - 2].pos.add((new Vec2(20, (i - 1.5) * 100)).normal().mutableScale(12 * lenCoef)));
var leftFoot = new Particle(composite.particles[len - 1].pos.add((new Vec2(-20, (i - 1.5) * 100)).normal().mutableScale(12 * lenCoef)))
composite.particles.push(rightFoot);
composite.particles.push(leftFoot);
composite.legs.push(rightFoot);
composite.legs.push(leftFoot);
len = composite.particles.length;
composite.constraints.push(new DistanceConstraint(composite.particles[len - 4], composite.particles[len - 2], legSeg4Stiffness));
composite.constraints.push(new DistanceConstraint(composite.particles[len - 3], composite.particles[len - 1], legSeg4Stiffness));
composite.constraints.push(new AngleConstraint(composite.particles[len - 6], composite.particles[len - 4], composite.particles[len - 2], joint3Stiffness));
composite.constraints.push(new AngleConstraint(composite.particles[len - 6 + 1], composite.particles[len - 4 + 1], composite.particles[len - 2 + 1], joint3Stiffness));
composite.constraints.push(new AngleConstraint(composite.particles[len - 8], composite.particles[len - 6], composite.particles[len - 4], joint2Stiffness));
composite.constraints.push(new AngleConstraint(composite.particles[len - 8 + 1], composite.particles[len - 6 + 1], composite.particles[len - 4 + 1], joint2Stiffness));
composite.constraints.push(new AngleConstraint(composite.particles[0], composite.particles[len - 8], composite.particles[len - 6], joint1Stiffness));
composite.constraints.push(new AngleConstraint(composite.particles[0], composite.particles[len - 8 + 1], composite.particles[len - 6 + 1], joint1Stiffness));
composite.constraints.push(new AngleConstraint(composite.particles[1], composite.particles[0], composite.particles[len - 8], bodyJointStiffness));
composite.constraints.push(new AngleConstraint(composite.particles[1], composite.particles[0], composite.particles[len - 8 + 1], bodyJointStiffness));
}
this.composites.push(composite);
return composite;
}
VerletJS.prototype.spiderweb = function (origin, radius, segments, depth) {
var stiffness = 0.6;
var tensor = 0.3;
var stride = (2 * Math.PI) / segments;
var n = segments * depth;
var radiusStride = radius / n;
var i, c;
var composite = new this.Composite();
// particles
for (i = 0; i < n; ++i) {
var theta = i * stride + Math.cos(i * 0.4) * 0.05 + Math.cos(i * 0.05) * 0.2;
var shrinkingRadius = radius - radiusStride * i + Math.cos(i * 0.1) * 20;
var offy = Math.cos(theta * 2.1) * (radius / depth) * 0.2;
composite.particles.push(new Particle(new Vec2(origin.x + Math.cos(theta) * shrinkingRadius, origin.y + Math.sin(theta) * shrinkingRadius + offy)));
}
for (i = 0; i < segments; i += 4)
composite.pin(i);
// constraints
for (i = 0; i < n - 1; ++i) {
// neighbor
composite.constraints.push(new DistanceConstraint(composite.particles[i], composite.particles[i + 1], stiffness));
// span rings
var off = i + segments;
if (off < n - 1)
composite.constraints.push(new DistanceConstraint(composite.particles[i], composite.particles[off], stiffness));
else
composite.constraints.push(new DistanceConstraint(composite.particles[i], composite.particles[n - 1], stiffness));
}
composite.constraints.push(new DistanceConstraint(composite.particles[0], composite.particles[segments - 1], stif