Java Code Examples for processing.core.PGraphics#ellipse()

The following examples show how to use processing.core.PGraphics#ellipse() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: QuadSurface.java    From sketch-mapper with MIT License 6 votes vote down vote up
/**
 * Draws the Cornerpoints
 *
 * @param g
 * @param x
 * @param y
 * @param selected
 * @param cornerIndex
 */
private void renderCornerPoint(PGraphics g, float x, float y, boolean selected, int cornerIndex) {
    g.noFill();
    g.strokeWeight(2);
    if (selected) {
        g.stroke(QuadSurface.SELECTED_CORNER_MARKER_COLOR);
    } else {
        g.stroke(QuadSurface.CORNER_MARKER_COLOR);
    }
    if (cornerIndex == getSelectedCorner() && isSelected()) {
        g.fill(QuadSurface.SELECTED_CORNER_MARKER_COLOR, 100);
        g.stroke(QuadSurface.SELECTED_CORNER_MARKER_COLOR);
    }
    g.ellipse(x, y, 10, 10);
    g.line(x, y - 5, x, y + 5);
    g.line(x - 5, y, x + 5, y);
}
 
Example 2
Source File: BezierSurface.java    From sketch-mapper with MIT License 6 votes vote down vote up
/**
 * Draws the bezier points
 *
 * @param g
 * @param x
 * @param y
 * @param selected
 * @param cornerIndex
 */
private void renderBezierPoint(PGraphics g, float x, float y, boolean selected, int cornerIndex) {
    g.noFill();
    g.strokeWeight(1);
    if (selected) {
        g.stroke(BezierSurface.SELECTED_CORNER_MARKER_COLOR);
    } else {
        g.stroke(BezierSurface.CORNER_MARKER_COLOR);
    }
    if (cornerIndex == getSelectedBezierControl() && isSelected()) {
        g.fill(BezierSurface.SELECTED_CORNER_MARKER_COLOR, 100);
        g.stroke(BezierSurface.SELECTED_CORNER_MARKER_COLOR);
    }
    g.ellipse(x, y, 10, 10);
    g.line(x, y - 5, x, y + 5);
    g.line(x - 5, y, x + 5, y);
}
 
Example 3
Source File: BezierSurface.java    From sketch-mapper with MIT License 6 votes vote down vote up
/**
 * Draws the Corner points
 *
 * @param g
 * @param x
 * @param y
 * @param selected
 * @param cornerIndex
 */
private void renderCornerPoint(PGraphics g, float x, float y, boolean selected, int cornerIndex) {
    g.noFill();
    g.strokeWeight(2);
    if (selected) {
        g.stroke(BezierSurface.SELECTED_CORNER_MARKER_COLOR);
    } else {
        g.stroke(BezierSurface.CORNER_MARKER_COLOR);
    }
    if (cornerIndex == getSelectedCorner() && isSelected()) {
        g.fill(BezierSurface.SELECTED_CORNER_MARKER_COLOR, 100);
        g.stroke(BezierSurface.SELECTED_CORNER_MARKER_COLOR);
    }
    g.ellipse(x, y, 10, 10);
    g.line(x, y - 5, x, y + 5);
    g.line(x - 5, y, x + 5, y);
}
 
Example 4
Source File: Demo_MultichannelAudio_BeadsJack.java    From haxademic with MIT License 5 votes vote down vote up
public void update(PGraphics pg) {
	// draw stage
	pg.push();
	pg.noFill();
	pg.stroke(255);
	PG.setDrawCenter(pg);
	PG.setCenterScreen(pg);
	pg.ellipse(0, 0, radius * 2, radius * 2);
	pg.pop();
	
	// draw speakers
	for (int i = 0; i < numSpeakers; i++) {
		speakers[i].update(pg);
	}
}
 
Example 5
Source File: LightBar.java    From haxademic with MIT License 5 votes vote down vote up
protected void drawNumberValue(PGraphics pg, int val) {
	// channel info text
	pg.push();
	pg.translate(0, 0);
	pg.fill(255);
	pg.noStroke();
	float ellipseW = (val > 99) ? 30 : 20;	// make wider for 3 digits
	pg.ellipse(midPoint.x, midPoint.y, ellipseW, 20);

	PFont font = FontCacher.getFont(DemoAssets.fontOpenSansPath, 12);
	FontCacher.setFontOnContext(pg, font, P.p.color(0), 1f, PTextAlign.CENTER, PTextAlign.CENTER);
	pg.text(val+"", midPoint.x, midPoint.y - 2, 30, 20);
	pg.pop();

}
 
Example 6
Source File: Shapes.java    From haxademic with MIT License 5 votes vote down vote up
public static void drawLineOfCircles(PGraphics pg, float startX, float startY, float endX, float endY) {
		// set context
		pg.noStroke();
		PG.setDrawCenter(pg);

		// config
		float stepSize = 10f;
		float spacing = stepSize * 1.5f;
		float distance = MathUtil.getDistance(startX, startY, endX, endY);
		float numToDraw = P.floor(distance / spacing);
		float endPadding = 2;
		float colorFreq = 0.01f;
		float colorStartOsc = P.p.frameCount * 0.03f;

		// draw debug endpoints
//		pg.fill(0, 255, 0);
//		pg.ellipse(startX, startY, stepSize * 2f, stepSize * 2f);
//		pg.fill(255, 0, 0);
//		pg.ellipse(endX, endY, stepSize * 2f, stepSize * 2f);

		// draw dots
//		pg.fill(255);
//		pg.text(numToDraw+"", 10, 20);
		for (float i = endPadding; i <= numToDraw - endPadding; i++) {
			float lineProgress = i / numToDraw;
			float curX = P.lerp(startX, endX, lineProgress);
			float curY = P.lerp(startY, endY, lineProgress);
			float curDist = MathUtil.getDistance(startX, startY, curX, curY);
			float oscVal = colorStartOsc - curDist * colorFreq;
//			float dotOsc = P.sin(P.map(oscVal, 0, P.TWO_PI, 0, P.PI));
			float dotOsc = P.sin(-oscVal % P.HALF_PI + P.PI);
			float colorOsc = 255 - 200f * dotOsc;
			pg.fill(colorOsc);
			float sizeOsc =  P.map(colorOsc, 0, 255, 0.3f, 1);
			pg.ellipse(curX, curY, stepSize * sizeOsc, stepSize * sizeOsc);
		}
	}
 
Example 7
Source File: SavedPointUI.java    From haxademic with MIT License 5 votes vote down vote up
protected void drawPoint(PGraphics pg) {
	PG.setDrawCenter(pg);
	pg.noFill();
	if(active) {
		pg.stroke(0, 255, 0);
	} else {
		pg.stroke(255);
	}
	pg.strokeWeight((active) ? 3 : 1.5f);
	float indicatorSize = 20f + 3f * P.sin(P.p.frameCount / 10f);
	pg.ellipse(position.x, position.y, indicatorSize, indicatorSize);
	pg.strokeWeight(1f);
	pg.rect(position.x, position.y, 3, 3);
	PG.setDrawCorner(pg);
}
 
Example 8
Source File: BaseSavedQuadUI.java    From haxademic with MIT License 5 votes vote down vote up
protected void showMappedRect(PGraphics pg) {
	pg.noFill();
	pg.stroke(0, 255, 0);
	pg.strokeWeight(1);
	pg.line(topLeft.x, topLeft.y, topRight.x, topRight.y);
	pg.line(topRight.x, topRight.y, bottomRight.x, bottomRight.y);
	pg.line(bottomRight.x, bottomRight.y, bottomLeft.x, bottomLeft.y);
	pg.line(bottomLeft.x, bottomLeft.y, topLeft.x, topLeft.y);
	pg.ellipse(center.x - 4, center.y - 4, 8, 8);
}
 
Example 9
Source File: BaseSavedQuadUI.java    From haxademic with MIT License 5 votes vote down vote up
protected void drawPoint(PGraphics pg, Point point) {
	PG.setDrawCenter(pg);
	pg.fill(255, 75);
	pg.stroke(0, 255, 0);
	pg.strokeWeight(2);
	float indicatorSize = 20f + 3f * P.sin(P.p.frameCount / 10f);
	pg.ellipse(point.x, point.y, indicatorSize, indicatorSize);
	PG.setDrawCorner(pg);
}
 
Example 10
Source File: MoireProposal.java    From haxademic with MIT License 5 votes vote down vote up
public void drawPointOnFloor(PGraphics tex) {
	float circleSize = tex.width * 0.1f * (1f + 0.2f * P.sin(8f * FrameLoop.progressRads()));
	tex.beginDraw();
	PG.setDrawCenter(p);
	tex.fill(255);
	tex.stroke(0);
	tex.strokeWeight(7);
	tex.ellipse(tex.width / 2, tex.height * 0.785f, circleSize, circleSize);
	tex.endDraw();
	PG.setDrawCorner(p);
}
 
Example 11
Source File: Demo_MultichannelAudio_BeadsJack.java    From haxademic with MIT License 5 votes vote down vote up
public void update(PGraphics pg) {
	// draw stage
	pg.push();
	pg.noFill();
	pg.stroke(0, 0, 255);
	PG.setDrawCenter(pg);
	PG.setCenterScreen(pg);
	pg.ellipse(position.x, position.y, 30, 30);
	pg.pop();
}
 
Example 12
Source File: ConstellationPointMarker.java    From constellation with Apache License 2.0 5 votes vote down vote up
@Override
public boolean draw(final PGraphics graphics, final List<MapPosition> positions, final UnfoldingMap map) {
    if (positions.isEmpty() || isHidden()) {
        return false;
    }

    final float x = positions.get(0).x;
    final float y = positions.get(0).y;

    graphics.pushStyle();

    if (size > MarkerUtilities.DEFAULT_SIZE) {
        graphics.strokeWeight(strokeWeight);
        graphics.stroke(strokeColor);
        graphics.fill(getFillColor());
        graphics.ellipseMode(PConstants.RADIUS);
        graphics.ellipse(x, y, size, size);
    } else {
        TEMPLATE_IMAGE.loadPixels();
        for (int i = 0; i < TEMPLATE_IMAGE.width * TEMPLATE_IMAGE.height; i++) {
            final int[] pixelArgb = MarkerUtilities.argb(TEMPLATE_IMAGE.pixels[i]);
            if (!(pixelArgb[0] == 0 || (pixelArgb[1] == 0 && pixelArgb[2] == 0 && pixelArgb[3] == 0))) {
                TEMPLATE_IMAGE.pixels[i] = getFillColor();
            }
        }
        TEMPLATE_IMAGE.updatePixels();

        graphics.imageMode(PConstants.CORNER);
        graphics.image(TEMPLATE_IMAGE, x - POINT_X_OFFSET, y - POINT_Y_OFFSET);
    }

    graphics.popStyle();

    return true;
}
 
Example 13
Source File: Demo_MultichannelAudio_BeadsJack.java    From haxademic with MIT License 5 votes vote down vote up
public void update(PGraphics pg) {
	// draw
	pg.push();
	pg.noFill();
	pg.stroke(0, 255, 0);
	PG.setDrawCenter(pg);
	PG.setCenterScreen(pg);
	pg.ellipse(position.x, position.y, 20, 20);
	pg.pop();
	
	// set gains
	for (int i = 0; i < outputs; i++) {
		// get dist to speaker
		PVector speakerPos = stage.getSpeaker(i).position();
		float dist = speakerPos.dist(position);
		float distToGain = P.map(dist, 0, stage.radius() * 2, 1, 0);
		distToGain = P.constrain(distToGain, 0, 1);
		gains[i].setGain(distToGain);
		
		// draw debug to speakers
		pg.push();
		pg.noFill();
		pg.stroke(0, 255 * distToGain, 0);
		PG.setDrawCenter(pg);
		PG.setCenterScreen(pg);
		pg.line(position.x, position.y, speakerPos.x, speakerPos.y);
		float midX = (position.x + speakerPos.x) / 2f;
		float midY = (position.y + speakerPos.y) / 2f;
		pg.text(distToGain, midX, midY);
		pg.pop();
	}
}
 
Example 14
Source File: MultiSimpleCalibrator.java    From PapARt with GNU Lesser General Public License v3.0 5 votes vote down vote up
public static void sin(PApplet parent, PGraphics g, int amt, float freq, int xDiff, float size) {
    float v = (PApplet.sin((float) (parent.millis()) / 1000f * PConstants.TWO_PI * freq) + 1f) / 2f;
    g.noStroke();
    g.ellipseMode(CENTER);
    g.fill(v * amt);
    g.ellipse(-xDiff, 0, size, size);
    g.ellipse(0, 0, size, size);
    g.ellipse(xDiff, 0, size, size);
}
 
Example 15
Source File: MeshLineSegment.java    From haxademic with MIT License 4 votes vote down vote up
public void update( PGraphics pg, MODE mode, int color, float ampTotal, float amp ) {
//		if( mode == MODE.MODE_EQ_TOTAL ) {
//			pg.strokeWeight( P.constrain( ampTotal * .5f, 0, 1 ) );
//			pg.stroke(color);
//			pg.line( _point1.x, _point1.y, _point2.x, _point2.y );
//		} else 
		if( mode == MODE.MODE_EQ_BARS_BLACK ) {
			pg.strokeWeight( P.constrain( ampTotal * 1.0f, 1, 3 ) );
			pg.stroke(0);
			pg.line( _point1.x, _point1.y, _point2.x, _point2.y );
		} else if( mode == MODE.MODE_DOTS ) {
			pg.noStroke();
			pg.fill(color, P.constrain(amp * 10, 0, 255));
			float ampNormalized = P.constrain( amp * 2.f, 0, 4 );
			pg.ellipse( _point1.x, _point1.y, ampNormalized, ampNormalized );
		} 
//		else if( mode == MODE.MODE_WAVEFORMS ) {
//			PG.setDrawCorner(pg);
//			
//			amp = 5;
//			
//			if(waveformShapeFrameDrew != P.p.frameCount) {
//				for (int i = 0; i < waveformShape.getVertexCount()-2; i+=2) {
//					waveformShape.setVertex( i, waveformShape.getVertexX(i), P.p._waveformData._waveform[i] * amp );
//				}
//				waveformShapeFrameDrew = P.p.frameCount;
//			}
//						
//			waveformShape.disableStyle();
//			pg.noFill();
//			pg.stroke(color);
//			pg.strokeWeight(1);
//			pg.pushMatrix();
//			pg.translate( _point2.x, _point2.y );
//			pg.rotate(_radians);
//			pg.shape(waveformShape, 0, 0, _length, waveformShape.height);
//			
////			pg.translate( (_point1.x + _point2.x)/2f, (_point1.y + _point2.y)/2f );
////			for (int i = 1; i < waveformData._waveform.length; i++ ) {			
////				pg.line( 
////						startX + (i-1) * _spacing,
////						waveformData._waveform[(i-1)] * amp,
////						startX + i * _spacing,
////						waveformData._waveform[i] * amp 
////				);
////			}
//			pg.popMatrix();
//		} 
//		else if( mode == MODE.MODE_EQ_BARS ) {
//			pg.strokeWeight( P.constrain( amp * 0.3f, 0, 1 ) );
//			pg.stroke(color);
//			pg.line( _point1.x, _point1.y, _point2.x, _point2.y );
//		} 
		else if( mode == MODE.MODE_LINE_EXTEND ) {
			pg.strokeWeight( 1f );
			pg.stroke(color, 147);

			_utilVec.set( _point2 );
			_utilVec.lerp( _point1, P.constrain(amp/10f, 0f, 1f) );
			pg.line( _utilVec.x, _utilVec.y, _point2.x, _point2.y );

			_utilVec.set( _point1 );
			_utilVec.lerp( _point2, P.constrain(amp/10f, 0f, 1f) );
			pg.line( _utilVec.x, _utilVec.y, _point1.x, _point1.y );
		} else if( mode == MODE.MODE_NONE ) {
			// do nothing
		} else if( mode == MODE.MODE_PARTICLES ) {
			// do nothing
		} else if( mode == MODE.MODE_PERLIN) {
			float noise = P.p.noise(
					_point1.x/5f + P.p.noise(P.p.frameCount/100f), 
					_point1.y/10f + P.p.noise(P.p.frameCount/50f) 
			);
			pg.strokeWeight( 1f );
			pg.stroke(color, noise * 255f);
			pg.line( _point1.x, _point1.y, _point2.x, _point2.y );
//		} else if( mode == MODE.MODE_PROGRESS_BAR ) {
//			_progress += _progressDir * ( amp/100f );
//			if(_progressDir == 1 && _progress > 1) {
//				_progressDir = -1;
//				_progress = 1;
//			} else if(_progressDir == -1 && _progress < 0) {
//				_progressDir = 1;
//				_progress = 0;
//			} 
//			_utilLastVec.set(_utilVec);
//			
////			pg.noStroke();
////			pg.fill(color);
//			pg.noFill();
//			pg.stroke(color, 210);
//			pg.strokeWeight(1.3f);
//			_utilVec.set( _point2 );
//			_utilVec.lerp( _point1, _progress );
//			// pg.ellipse( _utilVec.x, _utilVec.y, 2, 2 );
//			pg.line( _utilVec.x, _utilVec.y, _utilLastVec.x, _utilLastVec.y );
//
		}
	}
 
Example 16
Source File: Demo_KinectV1MultiCamWrapper.java    From haxademic with MIT License 4 votes vote down vote up
protected int drawKinectDepthPixels(KinectWrapperV1 kinect, PGraphics buffer, int pixelColor, boolean drawAllData) {
	// open context
	buffer.beginDraw();
	if(drawAllData == true) buffer.background(0, 0);
	buffer.noStroke();
	buffer.fill(pixelColor);

	// loop through kinect data within player's control range
	float pixelDepth;
	float avgX = 0;
	float avgY = 0;
	float numPoints = 0;
	
	float kinectDepthZone = slider(KINECT_FAR) - slider(KINECT_NEAR);
	float distancePixels = (float) KinectWrapperV1.KWIDTH / kinectDepthZone;		// map distance to width
	float pixelSkip = slider(PIXEL_SIZE);
	// float pixelHalf = pixelSkip / 2f;
	
	// TODO: Switch to ONLY loop through kinect points that we need
	for ( int x = 0; x < DepthCameraSize.WIDTH; x += pixelSkip ) {
		for ( int y = 0; y < KinectWrapperV2.KHEIGHT; y += pixelSkip ) {
			pixelDepth = kinect.getDepthAt( x, y );
			if(pixelDepth != 0 && pixelDepth > slider(KINECT_NEAR) && pixelDepth < slider(KINECT_FAR)) {
				// draw depth points
				float userZ = P.map(pixelDepth, slider(KINECT_NEAR), slider(KINECT_FAR), 0, kinectDepthZone * distancePixels);
				if(drawAllData == true || (y > slider(KINECT_TOP) && y < slider(KINECT_BOTTOM))) {
					buffer.rect(x - 5, userZ - 5, 10, 10);
				}
				
				// calc data processing
				numPoints++;
				avgX += x;
				avgY += userZ;
			}
		}
	}
	
	// show CoM
	buffer.fill(pixelColor);
	if(drawAllData == false) buffer.ellipse(avgX / numPoints, avgY / numPoints, 20, 20);
	
	// close buffer
	buffer.endDraw();
	return (int) numPoints;
}
 
Example 17
Source File: SurfaceMapper.java    From sketch-mapper with MIT License 4 votes vote down vote up
/**
 * Render method used when calibrating. Shouldn't be used for final rendering.
 *
 * @param glos
 */
public void render(PGraphics glos) {
    //        glos.beginDraw();
    //        glos.endDraw();
    if (MODE == MODE_CALIBRATE) {
        parent.cursor();
        glos.beginDraw();

        if (this.isUsingBackground()) {
            glos.image(backgroundTexture, 0, 0, width, height);
        }

        glos.fill(0, 40);
        glos.noStroke();
        glos.rect(-2, -2, width + 4, height + 4);
        glos.stroke(255, 255, 255, 40);
        glos.strokeWeight(1);
        /*
         * float gridRes = 32.0f;
*
* float step = (float) (width / gridRes);
*
* for (float i = 1; i < width; i += step) { glos.line(i, 0, i, parent.height); }
*
* step = (float) (height / gridRes);
*
* for (float i = 1; i < width; i += step) { glos.line(0, i, parent.width, i); }
*/
        glos.stroke(255);
        glos.strokeWeight(2);
        glos.line(1, 1, width - 1, 1);
        glos.line(width - 1, 1, width - 1, height - 1);
        glos.line(1, height - 1, width - 1, height - 1);
        glos.line(1, 1, 1, height - 1);
        glos.endDraw();

        for (int i = 0; i < surfaces.size(); i++) {
            surfaces.get(i).render(glos);
        }

        // Draw circles for SelectionDistance or SnapDistance (snap if CMD
        // is down)
        glos.beginDraw();
        if (enableSelectionMouse) {
            if (!ctrlDown) {
                glos.ellipseMode(PApplet.CENTER);
                glos.fill(this.getSelectionMouseColor(), 100);
                glos.noStroke();
                glos.ellipse(parent.mouseX, parent.mouseY, this.getSelectionDistance() * 2, this.getSelectionDistance() * 2);
            } else {
                glos.ellipseMode(PApplet.CENTER);
                glos.fill(255, 0, 0, 100);
                glos.noStroke();
                glos.ellipse(parent.mouseX, parent.mouseY, this.getSnapDistance() * 2, this.getSnapDistance() * 2);
            }
        }

        if (selectionTool != null && !disableSelectionTool) {
            glos.stroke(255, 100);
            glos.strokeWeight(1);
            glos.fill(0, 200, 255, 50);
            glos.rect(selectionTool.x, selectionTool.y, selectionTool.width, selectionTool.height);
            glos.noStroke();
        }

        glos.endDraw();

    } else {
        parent.noCursor();
    }
}
 
Example 18
Source File: DetectedMarker.java    From PapARt with GNU Lesser General Public License v3.0 4 votes vote down vote up
public void drawSelf(PGraphics g, int size) {
    for (int i = 0; i < 8; i += 2) {
        g.ellipse((float) corners[i], (float) corners[i + 1], size, size);
    }
}
 
Example 19
Source File: LightBar.java    From haxademic with MIT License 4 votes vote down vote up
public void update(PGraphics pg, int index) {
	// update midpoint
	midPoint.set(point1);
	midPoint.lerp(point2, 0.5f);
	
	// draw
	if(active) {
		// draw enclosing circle to highlight tube
		float highlightSize = point1.dist(point2) + 50;
		pg.noFill();
		pg.strokeWeight(1);
		pg.stroke(0, 255, 0);
		pg.ellipse(midPoint.x, midPoint.y, highlightSize, highlightSize);
		
		// flash color
		int rainbow = P.p.color(
				127 + 127 * P.sin(P.p.frameCount * 0.1f),
				127 + 127 * P.sin(P.p.frameCount * 0.15f),
				127 + 127 * P.sin(P.p.frameCount * 0.225f));
		dmxFixture.color().setCurrentInt((P.p.frameCount % 16 < 8) ? rainbow : P.p.color(0));
		// dmxFixture.color().setCurrentInt(0xffff0000);
	}
	
	// draw light
	pg.noStroke();
	pg.fill(dmxFixture.color().colorInt());
	pg.push();
	pg.translate(midPoint.x, midPoint.y);
	pg.rotate(MathUtil.getRadiansToTarget(point2.x, point2.y, point1.x, point1.y));
	pg.rect(0, 0, point1.dist(point2), 5);
	pg.pop();
	
	// small circular ends
	pg.ellipse(point1.x, point1.y, 3, 3);
	pg.ellipse(point2.x, point2.y, 3, 3);
	
	// show text labels overlay
	if(P.store.getBoolean(DMXEditor.SHOW_DMX_CHANNELS)) {
		drawNumberValue(pg, dmxChannel);
	}
	if(P.store.getBoolean(DMXEditor.SHOW_LIGHT_INDEX)) {
		drawNumberValue(pg, index);
	}
}
 
Example 20
Source File: ConstellationClusterMarker.java    From constellation with Apache License 2.0 4 votes vote down vote up
@Override
protected boolean draw(final PGraphics graphics, final List<MapPosition> positions, final UnfoldingMap map) {
    if (positions.isEmpty() || isHidden()) {
        return false;
    }

    clusterCenter = new MapPosition();
    positions.forEach(position -> {
        clusterCenter.add(position);
    });
    clusterCenter.div(positions.size());

    double diameter = 0;
    if (positions.size() > 1) {
        final MapPosition minPosition = new MapPosition(
                new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE});
        final MapPosition maxPosition = new MapPosition(
                new float[]{Float.MIN_VALUE, Float.MIN_VALUE, Float.MIN_VALUE});
        positions.forEach(position -> {
            minPosition.x = Math.min(position.x, minPosition.x);
            minPosition.y = Math.min(position.y, minPosition.y);
            maxPosition.x = Math.max(position.x, maxPosition.x);
            maxPosition.y = Math.max(position.y, maxPosition.y);
        });
        diameter = Math.sqrt(Math.pow((maxPosition.x - minPosition.x), 2)
                + Math.pow((maxPosition.y - minPosition.y), 2));
    }
    clusterRadius = Math.max((float) diameter / 2, MIN_RADIUS);

    graphics.strokeWeight(size == MarkerUtilities.DEFAULT_SIZE ? strokeWeight : size);
    graphics.stroke(strokeColor);
    graphics.fill(getFillColor());
    graphics.ellipseMode(PConstants.RADIUS);
    graphics.ellipse(clusterCenter.x, clusterCenter.y, clusterRadius, clusterRadius);

    final String clusterLabel = String.valueOf(clusterSize);
    graphics.fill(FONT_COLOR);
    graphics.textSize(FONT_SIZE);
    graphics.text(clusterLabel,
            clusterCenter.x - (CHAR_WIDTH * clusterLabel.length() * 0.6f),
            clusterCenter.y + (FONT_SIZE * 0.35f));

    return true;
}