2012-07-30 8 views
6

Ich möchte wissen, wie man einen Halbkreis in JavaFX zeichnet. Ich habe versucht, Shape und QuadCurve zu verwenden, aber ich konnte keinen perfekten Halbkreis bilden. HierZeichne einen Halbring - JavaFX

ist ein Bild von dem, was ich versuche zu ziehen:

enter image description here

Antwort

10

Das Bild, das Sie eigentlich ein halb-Ring verknüpft ist. Sie können es in JavaFX erhalten, indem Sie verschachtelte 2 Bögen und einige Linien zeichnen. Aber meine bevorzugte Methode ist die Path.

public class SemiDemo extends Application { 

    @Override 
    public void start(Stage primaryStage) { 

     Group root = new Group(); 
     root.getChildren().add(drawSemiRing(120, 120, 100, 50, Color.LIGHTGREEN, Color.DARKGREEN)); 
     root.getChildren().add(drawSemiRing(350, 350, 200, 30, Color.LIGHTSKYBLUE, Color.DARKBLUE)); 

     Scene scene = new Scene(root, 300, 250); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    private Path drawSemiRing(double centerX, double centerY, double radius, double innerRadius, Color bgColor, Color strkColor) { 
     Path path = new Path(); 
     path.setFill(bgColor); 
     path.setStroke(strkColor); 
     path.setFillRule(FillRule.EVEN_ODD); 

     MoveTo moveTo = new MoveTo(); 
     moveTo.setX(centerX + innerRadius); 
     moveTo.setY(centerY); 

     ArcTo arcToInner = new ArcTo(); 
     arcToInner.setX(centerX - innerRadius); 
     arcToInner.setY(centerY); 
     arcToInner.setRadiusX(innerRadius); 
     arcToInner.setRadiusY(innerRadius); 

     MoveTo moveTo2 = new MoveTo(); 
     moveTo2.setX(centerX + innerRadius); 
     moveTo2.setY(centerY); 

     HLineTo hLineToRightLeg = new HLineTo(); 
     hLineToRightLeg.setX(centerX + radius); 

     ArcTo arcTo = new ArcTo(); 
     arcTo.setX(centerX - radius); 
     arcTo.setY(centerY); 
     arcTo.setRadiusX(radius); 
     arcTo.setRadiusY(radius); 

     HLineTo hLineToLeftLeg = new HLineTo(); 
     hLineToLeftLeg.setX(centerX - innerRadius); 

     path.getElements().add(moveTo); 
     path.getElements().add(arcToInner); 
     path.getElements().add(moveTo2); 
     path.getElements().add(hLineToRightLeg); 
     path.getElements().add(arcTo); 
     path.getElements().add(hLineToLeftLeg); 

     return path; 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 

über die im Code verwendeten Formen für weitere Informationen zu Shape API von JavaFX finden.
Screenshot:

enter image description here

+0

Jahr, perfekt! : D Es ist genau das, was ich brauche ^^ Vielen Dank! – AwaX

+0

Wissen Sie, ob es eine einfache Möglichkeit gibt, den Drehpunkt eines Pfades zu ändern? – AwaX

+0

@AwaX path.setRotate (45); –

4

Vorschläge:

  • Wenn Sie keinen vollständigen Pfad Konturierung benötigen, können Sie nur eine nutzen Bogen.
  • Wenn Sie den Bogen nicht ausfüllen und nur den Umriss des Bogens verfolgen möchten, legen Sie die Füllung des Bogens auf null fest.
  • Wenn der Outline-Pfad des Bogens dick sein soll, legen Sie die Stroke-Parameter für den Bogen fest.
  • Wenn Sie einen dicken Bogen benötigen, der ebenfalls umrissen ist, dann ist es am besten, einen vollen Bogen zu definieren, wie in Uluks Antwort.

Beispielcode:

import javafx.application.Application; 
import javafx.scene.*; 
import javafx.scene.paint.Color; 
import javafx.scene.shape.*; 
import javafx.stage.Stage; 

public class SemiCircleSample extends Application { 
    @Override public void start(Stage stage) { 
    Arc arc = new Arc(50, 50, 25, 25, 0, 180); 
    arc.setType(ArcType.OPEN); 
    arc.setStrokeWidth(10); 
    arc.setStroke(Color.CORAL); 
    arc.setStrokeType(StrokeType.INSIDE); 
    arc.setFill(null); 

    stage.setScene(new Scene(new Group(arc), 100, 80)); 
    stage.show(); 
    } 

    public static void main(String[] args) { launch(args); } 
} 
+0

Danke, aber es ist ein voller Halbkreis, was ich zeichnen möchte, ist ein Halbkreis leer in der Mitte. Ich habe in meinem vorherigen Beitrag ein Beispiel eingefügt, das genau zeigt, was ich zeichnen möchte. – AwaX

+0

Aktualisierte Antwort zum Demonstrieren des Zeichnens eines Bogens mit einem angegebenen Strich und ohne Füllung (wodurch ein Halbringbild erzeugt wird). – jewelsea

+0

Vielen Dank für Ihr Update, Ihre Lösung ist bequemer, aber Sie können den Bogen nicht füllen, wie Sie sagten, also denke ich, dass ich die andere Lösung nehmen werde. – AwaX

0

Path.arcTo() Der Parameter SweepAngle bezieht sich auf den Rotationsgrad, wenn sweepAngle positiv ist der Lichtbogen im Uhrzeigersinn ist, wenn der Lichtbogen sweepAngle negativ ist gegen den Uhrzeigersinn ist.

ist in meiner Produktionsumgebung Dieser Code verwendet wird, zieht es sich um eine Halbkreis-Ring ein Bitmap-Bild verwendet wird, der Weg, auf dem Außenradius im Uhrzeigersinn geht, und gegen den Uhrzeigersinn auf dem Innenradius:

drawpercent = 0.85; //this draws a semi ring to 85% you can change it using your code. 
DegreesStart = -90; 
DegreesRotation = 180; 

radiusPathRectF = new android.graphics.RectF((float)CentreX - (float)Radius, (float)CentreY - (float)Radius, (float)CentreX + (float)Radius, (float)CentreY + (float)Radius); 
innerradiusPathRectF = new android.graphics.RectF((float)CentreX - (float)InnerRadius, (float)CentreY - (float)InnerRadius, (float)CentreX + (float)InnerRadius, (float)CentreY + (float)InnerRadius); 

Path p = new Path(); //TODO put this outside your draw() function, you should never have a "new" keyword inside a fast loop. 

       degrees = (360 + (DegreesStart)) % 360; 
       radians = (360 - degrees + 90) * Math.PI/180.0; 
       //radians = Math.toRadians(DegreesStart); 
       int XstartOuter = (int)Math.round((Math.cos(radians) * Radius + CentreX)); 
       int YstartOuter = (int)Math.round((Math.sin(-radians)* Radius + CentreY)); 
       int XstartInner = (int)Math.round((Math.cos(radians) * InnerRadius + CentreX)); 
       int YstartInner = (int)Math.round((Math.sin(-radians) * InnerRadius + CentreY)); 

       degrees = (360 + (DegreesStart + drawpercent * DegreesRotation)) % 360; 
       //radians = degrees * Math.PI/180.0; 
       radians = (360 - degrees + 90) * Math.PI/180.0; 
       //radians = Math.toRadians(DegreesStart + drawpercent * DegreesRotation); 
       int XendOuter = (int)Math.round((Math.cos(radians) * Radius + CentreX)); 
       int YendOuter = (int)Math.round((Math.sin(-radians) * Radius + CentreY)); 
       int XendInner = (int)Math.round((Math.cos(radians) * InnerRadius + CentreX)); 
       int YendInner = (int)Math.round((Math.sin(-radians) * InnerRadius + CentreY)); 

       //draw a path outlining the semi-circle ring. 
       p.moveTo(XstartInner, YstartInner); 
       p.lineTo(XstartOuter, YstartOuter); 
       p.arcTo(radiusPathRectF, (float)DegreesStart - (float)90, (float)drawpercent * (float)DegreesRotation); 
       p.lineTo(XendInner, YendInner); 
       p.arcTo(innerradiusPathRectF, (float)degrees - (float)90, -1 * (float)drawpercent * (float)DegreesRotation); 
       p.close(); 

       g.clipPath(p); 

       g.drawBitmap(bitmapCircularBarImage, bitmapRect0, bitmapRectXY, paint); 
2

Als ein Experiment habe ich versucht, dasselbe auf einem Canvas zu tun. Das ist, was ich kam mit, die Verwendung eines RadialGradient machen und die Funktion GraphicsContext.fillArc:

/** 
* 
* @param x Coordinate x of the centre of the arc 
* @param y Coordinate y of the centre of the arc 
* @param outer Outer radius of the arc 
* @param innerPercentage Inner radius of the arc, from 0 to 1 (as percentage) 
* @param arcStartAngle Start angle of the arc, in degrees 
* @param arcExtent Extent of the arc, in degrees 
*/ 
private void drawSemiCircle(float x, float y, float outer, float innerPercentage, float arcStartAngle, float arcExtent) { 
    RadialGradient rg = new RadialGradient(
      0, 
      0, 
      x, 
      y, 
      outer, 
      false, 
      CycleMethod.NO_CYCLE, 
      new Stop((innerPercentage + (.0 * innerPercentage)), Color.TRANSPARENT), 
      new Stop((innerPercentage + (.1 * innerPercentage)), Color.RED), 
      new Stop((innerPercentage + (.6 * innerPercentage)), Color.YELLOW), 
      new Stop((innerPercentage + (1 * innerPercentage)), Color.GREEN) 
    ); 
    gc.setFill(rg); 
    gc.fillArc(
      x - outer, 
      y - outer, 
      outer * 2, 
      outer * 2, 
      arcStartAngle, 
      arcExtent, 
      ArcType.ROUND 
    ); 
} 

Kernpunkte sind hier der Bogentyp als ArcType.ROUND und die Verwendung von Color.TRANSPARENT als die ersten Farbe.

drawSemiCircle(100, 100, 100, .5f, -45, 270); 

eine perfekte Lösung, aber es funktionierte für mich ist es nicht:

Dann kann es etwas entlang der Linie verwendet werden.

Verwandte Themen