2D-Grafik Umrandung eines Winkels (drawArc(..))

g-a-s-t

Aktives Mitglied
Hallo zusammen,

ich zeichne einen Kreis der in unterschiedlich große Stücke zerlegt wird. Diese Teile färbe ich mittels fillArc(.) und zeichne zusätzlich einen Rahmen um den Kreis drawArc(.).
Nun möchte ich jedoch diese unterschiedlich großen Teile mit einem Rahmen versehen. Dies versuche ich indem ich Linien als Begrenzung zeichne. Dazu berechne ich die entsprechenden Punkte auf dem Kreisbogen. Doch irgendwie will das nicht funktionieren. :noe:
Diese Endpunkte stimmen nicht mit den gefüllten Kreisauschnitten überein.

Schaut doch mal bitte über meinen Code-Schnipsel, vielleicht habt ihr eine Lösung. Was mache ich falsch? Allein der Mittelpunkt, von wo aus die Linien zum Rand des Kreises laufen, stimmt nicht.
Gibt es vielleicht auch eine andere Möglichkeit so ein Kreisausschnitt zu umranden?

Java:
Graphics2D g2 = (Graphics2D) getGraphics();

// Mittelpunktkoordinaten des Kreises
int MP_x = 80;       
int MP_y = 100;  
// Teile des Kreises als Winkelangabe
int[] arc = {180, 130, 43, 7};     

g2.setColor(Color.green);
g2.fillArc(20, 40, 120, 120, 90, -arc[0]);
        
g2.setColor(Color.orange);
g2.fillArc(20, 40, 120, 120, 90 - arc[0], -arc[1]);
        
g2.setColor(Color.red);
g2.fillArc(20, 40, 120, 120, 90 - (arc[0] + arc[1]), -arc[2]);
       
g2.setColor(Color.blue);
g2.fillArc(20, 40, 120, 120, 90 - (arc[0] + arc[1] + arc[2]), -arc[3]);
        
g2.setColor(Color.black);
g2.drawArc(20, 40, 120, 120, 0, 360);
        
for (int i = 0; i < 4; i++) {
        // Winkel in Bogenmaß
     	double angle = Math.toRadians(arc[i]);
	    	
       	// (Winkel * Radius) + Position 
    	int pX = (int) (Math.cos(angle) * 60.0) + MP_x;
    	int pY = (int) (Math.sin(angle) * 60.0) + MP_y;
			
    	g2.drawLine(103, 104, pX, pY);
}
 
also zuerst einmal:

Java:
		for (int i = 0; i < 4; i++)
		{
		        // Winkel in Bogenmaß
		        double angle = Math.toRadians(arc[i]);
		            
		        // (Winkel * Radius) + Position 
		        int pX = (int) ((Math.cos(angle) * 60.0) + MP_x);
		        int pY = (int) ((Math.sin(angle) * 60.0) + MP_y);
		            
		        g2.drawLine(MP_x, MP_y, pX, pY);
		}

also schonmal 2 sachen dazu

Java:
int pX = (int) ((Math.cos(angle) * 60.0) + MP_x);

ich habe da nochmal ne extra klammer drum gemacht, ist präziser für den fall das MP_x keine ganzzahl mehr ist...

Java:
g2.drawLine(MP_x, MP_y, pX, pY);

wenn du schon nen mittelpunkt definierst solltest du deinen rahmen auch in bezug zu diesem mittelpunkt zeichnen...

das ganze haut so auch noch nicht ganz hin (ist nicht korrekt gedreht), da hab ich aber auch NOCH keine lösung gefunden 😉
 
habe die Lösung gefunden

1) stellenweise zu ungenau
2) der 0punkt stimmte nicht
3) hast du das offset der vorherigen winkel als radient vergessen
4) ist der screen invertiert (von oben 0 bis unten (z.B. 768))

hab das ganze jetzt soweit zum funzen bekommen (habe dabei wohl bissel was umgebaut)
villeicht hilft es dir, deinen code entsprechend anzupassen

Java:
package drawKrams;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;

public class Drawkrams extends JFrame
{	
	List<Value> values = new ArrayList<Value>();
	
	private class Value
	{
		private double percent = 0.0;
		private Color color = Color.black;
		
		private Value() {};
		public Value(double percent, Color color)
		{
			this.percent = percent;
			this.color = color;
		}
		
		public Color getColor()
		{
			return color;
		}
		
		public double getPercent()
		{
			return percent;
		}
	}
	
	public Drawkrams()
	{
		// init percentages with color
		values.add(new Value(25.0, Color.yellow));
		values.add(new Value(25.0, Color.green));
		values.add(new Value(17.0, Color.cyan));
		values.add(new Value(33.0, Color.red));
		
		this.setSize(500,500);
		this.setVisible(true);
	}
	
	public static void main(String[] args)
	{
		new Drawkrams();
	}
	
	@Override
	public void paint(Graphics g)
	{
		super.paint(g);
		
		Graphics2D g2 = (Graphics2D) g;
		
		// Mittelpunktkoordinaten des Kreises
		// center of the screen
		int MP_x = this.getWidth() / 2;       
		int MP_y = this.getHeight() / 2;
		
		double angleOffset = 0;
		for (Value val : values)
		{
			g2.setColor(val.getColor());
					
			// draw filled arc
			g2.fillArc(MP_x-150, MP_y-150, 300, 300, (int)(angleOffset+0.5), (int)((val.getPercent() / 100 * 360)+0.5));
			
			// draw border
			g.setColor(Color.black);
			g2.drawArc(MP_x-150, MP_y-150, 300, 300, (int)(angleOffset+0.5), (int)((val.getPercent() / 100 * 360)+0.5));
			
			// update current angle for next loop-run
			angleOffset = angleOffset + (val.getPercent() / 100 * 360);
		}
		
		angleOffset = 0;
		g.setColor(Color.black);
		for (Value val : values)
		{
			// get angle as radiant
			// note: screen x 0,y 0 is TOP-left, so y so direction must be inverted (leading - )
			double angle = ( - (Math.toRadians((angleOffset + (val.getPercent() / 100 * 360)))));
			            
			// (Winkel * Radius) + Position (+ rounding 0.5)
			int pX = (int) (((Math.cos(angle) * 150.0) + MP_x) + 0.5);
			int pY = (int) (((Math.sin(angle) * 150.0) + MP_y) + 0.5);
			            
		    g2.drawLine(MP_x, MP_y, pX, pY);
		    g2.drawString(Double.toString(val.getPercent()), pX, pY);
		    angleOffset = angleOffset + (val.getPercent() / 100 * 360);
		}
	}
}
 
Und noch eine Ergänzung:

wenn dir das ganze etwas zu Pixelig ist, kannst du das hier nach super.paint(Graphics g) einfügen:

Java:
            Graphics2D g2 = (Graphics2D) g;
	    RenderingHints rh = new RenderingHints(
	             RenderingHints.KEY_ANTIALIASING,
	             RenderingHints.VALUE_ANTIALIAS_ON);
	    
	    g2.setRenderingHints(rh);
	    
	    g2.setStroke(new BasicStroke(1));
 

Neue Themen


Zurück
Oben