Skip to content Skip to sidebar Skip to footer

Draw A Circle (not Shaded) With Three.js

I am trying to draw a circle very similar to the orbital patterns on this website. I would like to use Three.js instead of pure WebGL.

Solution 1:

Three.js r50 added CircleGeometry. It can be seen (albeit with a face) in the WebGL Geometries example.

The first vertex in the geometry is created at the center of the circle (in r84, see CircleGeometry.js line 71, in r65, see CircleGeometry.js line 18), which is nifty if you are going for that "full Pac-Man" or "uninformative pie chart" look. Oh, and it appears to be necessary if you are going to use any material aside from LineBasicMaterial / LineDashedMaterial.

I've verified that the following code works in both r60 & r65:

var radius   = 100,
    segments = 64,
    material = newTHREE.LineBasicMaterial( { color: 0x0000ff } ),
    geometry = newTHREE.CircleGeometry( radius, segments );

// Remove center vertex
geometry.vertices.shift();

// Non closed circle with one open segment:
scene.add( newTHREE.Line( geometry, material ) );

// To get a closed circle use LineLoop instead (see also @jackrugile his comment):
scene.add( newTHREE.LineLoop( geometry, material ) );

PS: The "docs" now include a nice CircleGeometry interactive example: https://threejs.org/docs/#api/geometries/CircleGeometry

Solution 2:

The API changed slightly in newer versions of threejs.

var segmentCount = 32,
    radius = 100,
    geometry = newTHREE.Geometry(),
    material = newTHREE.LineBasicMaterial({ color: 0xFFFFFF });

for (var i = 0; i <= segmentCount; i++) {
    var theta = (i / segmentCount) * Math.PI * 2;
    geometry.vertices.push(
        newTHREE.Vector3(
            Math.cos(theta) * radius,
            Math.sin(theta) * radius,
            0));            
}

scene.add(newTHREE.Line(geometry, material));

Modify segmentCount to make the circle smoother or more jagged as needed by your scene. 32 segments will be quite smooth for small circles. For orbits such as those on the site you link you, you may want to have a few hundred.

Modify the order of the three components within the Vector3 constructor to choose the orientation of the circle. As given here, the circle will be aligned to the x/y plane.

Solution 3:

I used code that Mr.doob references in this github post.

var resolution = 100;
var amplitude = 100;
var size = 360 / resolution;

var geometry = newTHREE.Geometry();
var material = newTHREE.LineBasicMaterial( { color: 0xFFFFFF, opacity: 1.0} );
for(var i = 0; i <= resolution; i++) {
    var segment = ( i * size ) * Math.PI / 180;
    geometry.vertices.push( newTHREE.Vertex( newTHREE.Vector3( Math.cos( segment ) * amplitude, 0, Math.sin( segment ) * amplitude ) ) );         
}

var line = newTHREE.Line( geometry, material );
scene.add(line);

Solution 4:

This example is in the Three.js documentation:

var material = new THREE.MeshBasicMaterial({
    color: 0x0000ff
});

var radius = 5;
var segments = 32; //<-- Increase or decrease for more resolution I guessvar circleGeometry = new THREE.CircleGeometry( radius, segments );              
var circle = new THREE.Mesh( circleGeometry, material );
scene.add( circle );

Solution 5:

I had to do this lol:

function createCircle() {
    let circleGeometry = new THREE.CircleGeometry(1.0, 30.0);
    circleGeometry.vertices.splice(0, 1); //<= This.returnnew THREE.LineLoop(circleGeometry,
        new THREE.LineBasicMaterial({ color: 'blue' }));
}
let circle = createCircle();

Reason: Otherwise, it doesn't draw a "pure" circle, there's a line coming from the center to the rim of the circle, even if you use LineLoop instead of Line. Splicing (removing) the first vertex from the array is a hack but seems to do the trick. :)

(Note that apparently, according to mrienstra's answer, "Oh, and it appears to be necessary if you are going to use any material aside from LineBasicMaterial / LineDashedMaterial.")


If you want thickness, though, you're screwed ("Due to limitations of the OpenGL Core Profile with the WebGL renderer on most platforms linewidth will always be 1 regardless of the set value.")... Unless you use: https://github.com/spite/THREE.MeshLine

Code example for that is here: https://stackoverflow.com/a/61312721/1599699

Post a Comment for "Draw A Circle (not Shaded) With Three.js"