2012-07-30 11 views
6

मैं जानना चाहता हूं कि जावाएफएक्स में अर्द्ध सर्कल कैसे आकर्षित करें। मैंने आकार और क्वाडकुर्वे का उपयोग करने की कोशिश की लेकिन मैं एक परिपूर्ण अर्धचालक नहीं बना सका।अर्द्ध अंगूठी बनाएं - जावाएफएक्स

enter image description here

उत्तर

10

चित्र आप लिंक किए गए वास्तव में एक अर्द्ध अंगूठी है। आप इसे नेस्टेड 2 आर्क और कुछ लाइनों को खींचकर जावाएफएक्स में प्राप्त कर सकते हैं। लेकिन मेरा पसंदीदा तरीका 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); 
    } 
} 

कोड में इस्तेमाल किया आकार के बारे में अधिक जानकारी के लिए JavaFX की Shape API का संदर्भ लें।
स्क्रीनशॉट:

enter image description here

+0

साल, सही! : डी यह वही है जो मुझे चाहिए ^^ बहुत बहुत धन्यवाद! – AwaX

+0

क्या आप जानते हैं कि पथ के घूर्णन बिंदु को संशोधित करने का कोई आसान तरीका है या नहीं? – AwaX

+0

@AwaX path.setRotate (45); –

4

सुझाव::

  • आप एक पूर्ण रूपरेखा पथ की जरूरत नहीं है, तो आप सिर्फ एक का उपयोग कर सकते

    यहाँ है कि मैं क्या आकर्षित करने के लिए कोशिश कर रहा हूँ की एक तस्वीर है आर्क।

  • यदि आपको आर्क से भरने की आवश्यकता नहीं है और केवल आर्क के रूपरेखा पथ का पता लगाना चाहते हैं, तो आर्क को भरने के लिए सेट करें।
  • यदि आप आर्क मोटाई के रूपरेखा पथ चाहते हैं, तो चाप पर स्ट्रोक पैरामीटर सेट करें।
  • यदि आपको एक मोटी चाप की भी आवश्यकता है जिसे उल्लिखित किया गया है, तो Uluk के उत्तर में एक पूर्ण चाप को परिभाषित करना सबसे अच्छा है।

नमूना कोड:

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

धन्यवाद, लेकिन यह एक पूर्ण अर्ध सर्कल है, जिसे मैं आकर्षित करना चाहता हूं वह केंद्र में एक अर्ध सर्कल खाली है। मैंने अपनी पिछली पोस्ट में एक उदाहरण शामिल किया जो दिखा रहा है कि मैं क्या आकर्षित करने की कोशिश कर रहा हूं। – AwaX

+0

निर्दिष्ट स्ट्रोक के साथ एक चाप ड्राइंग का प्रदर्शन करने के लिए अद्यतन उत्तर और कोई भर नहीं (जो आधा रिंग छवि उत्पन्न करेगा)। – jewelsea

+0

आपके अपडेट के लिए बहुत बहुत धन्यवाद, आपका समाधान अधिक सुविधाजनक है लेकिन आप जैसे चाप को भर नहीं सकते हैं, इसलिए मुझे लगता है कि मैं दूसरा समाधान लेगा। – AwaX

0

Path.arcTo() पैरामीटर SweepAngle, रोटेशन डिग्री को संदर्भित करता है, तो sweepAngle सकारात्मक है चाप, दक्षिणावर्त है अगर sweepAngle नकारात्मक है चाप वामावर्त है।

इस कोड को मेरी उत्पादन वातावरण में प्रयोग किया जाता है, यह ड्रॉ एक अर्द्ध वृत्त एक बिटमैप छवि का उपयोग कर अंगूठी, पथ बाहरी त्रिज्या पर दक्षिणावर्त चला जाता है, और मन की त्रिज्या पर वामावर्त:

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

एक प्रयोग के रूप में, मैंने एक ही चीज़ को कैनवास पर करने की कोशिश की।

/** 
* 
* @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 
    ); 
} 

प्रमुख बिंदु यहाँ ArcType.ROUND के रूप में चाप प्रकार और रंग के रूप में पहले Color.TRANSPARENT के उपयोग कर रहे हैं: यह है कि मैं क्या के साथ आया था, एक RadialGradient और समारोह GraphicsContext.fillArc का इस्तेमाल कर रही है।

तो यह रेखा के साथ कुछ किया जा सकता है:

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

यह एक आदर्श समाधान नहीं है, लेकिन यह मेरे लिए काम किया।