Skip to content

Instantly share code, notes, and snippets.

@aceslowman
Last active January 2, 2022 11:08
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aceslowman/d2fbad8b0f21656007e337543866539c to your computer and use it in GitHub Desktop.
Save aceslowman/d2fbad8b0f21656007e337543866539c to your computer and use it in GitHub Desktop.
Capsule Geometry for ThreeJS
import * as THREE from "three";
/*
Implemented from a technique described here:
http://paulbourke.net/geometry/capsule/
PID2 taken from Paul Bourke's paulslib.h
PID2 = 1.570796326794896619231322;
ISSUES:
add ability to add loops in middle segment
COOL THINGS:
using a positive PID2 will invert the caps
*/
const CapsuleGeometry = (radius = 1, height = 2, N = 32) => {
const geometry = new THREE.Geometry();
const TWOPI = Math.PI*2;
const PID2 = 1.570796326794896619231322;
const normals = [];
// top cap
for(let i = 0; i <= N/4; i++){
for(let j = 0; j <= N; j++){
let theta = j * TWOPI / N;
let phi = -PID2 + Math.PI * i / (N/2);
let vertex = new THREE.Vector3();
let normal = new THREE.Vector3();
vertex.x = radius * Math.cos(phi) * Math.cos(theta);
vertex.y = radius * Math.cos(phi) * Math.sin(theta);
vertex.z = radius * Math.sin(phi);
vertex.z -= height/2;
normal.x = vertex.x;
normal.y = vertex.y;
normal.z = vertex.z;
geometry.vertices.push(vertex);
normals.push(normal);
}
}
// bottom cap
for(let i = N/4; i <= N/2; i++){
for(let j = 0; j <= N; j++){
let theta = j * TWOPI / N;
let phi = -PID2 + Math.PI * i / (N/2);
let vertex = new THREE.Vector3();
let normal = new THREE.Vector3();
vertex.x = radius * Math.cos(phi) * Math.cos(theta);
vertex.y = radius * Math.cos(phi) * Math.sin(theta);
vertex.z = radius * Math.sin(phi);
vertex.z += height/2;
normal.x = vertex.x;
normal.y = vertex.y;
normal.z = vertex.z;
geometry.vertices.push(vertex);
normals.push(normal);
}
}
for(let i = 0; i <= N/2; i++){
for(let j = 0; j < N; j++){
let vec = new THREE.Vector4(
i * ( N + 1 ) + j ,
i * ( N + 1 ) + ( j + 1 ) ,
( i + 1 ) * ( N + 1 ) + ( j + 1 ) ,
( i + 1 ) * ( N + 1 ) + j
);
if(i==N/4){
let face_1 = new THREE.Face3(vec.x,vec.y,vec.z,[ //ok
normals[vec.x],
normals[vec.y],
normals[vec.z]
]);
let face_2 = new THREE.Face3(vec.x,vec.z,vec.w,[
normals[vec.x],
normals[vec.z],
normals[vec.w]
]);
geometry.faces.push(face_2);
geometry.faces.push(face_1);
}else{
let face_1 = new THREE.Face3(vec.x,vec.y,vec.z,[
normals[vec.x],
normals[vec.y],
normals[vec.z]
]);
let face_2 = new THREE.Face3(vec.x,vec.z,vec.w,[
normals[vec.x],
normals[vec.z],
normals[vec.w]
]);
geometry.faces.push(face_1);
geometry.faces.push(face_2);
}
}
// if(i==(N/4)) break; // N/4 is when the center segments are solved
}
geometry.computeFaceNormals();
// geometry.computeVertexNormals();
return geometry;
}
export default CapsuleGeometry;
@kaphula
Copy link

kaphula commented Dec 23, 2021

Any license for this one?

@aceslowman
Copy link
Author

@kaphula use it however!

@kaphula
Copy link

kaphula commented Dec 28, 2021

Cool, thanks!

@amitukind
Copy link

Not working with ThreeJS Latest version 136. Any solutions ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment