2012-10-24 57 views
6

我在JavaFX中使用CubicCurve很困難。如何畫一個例子:y = x^3?繪製曲線的機制看起來非常笨拙。CubicCurve JavaFX

也有可能將曲線的一個端點連接到另一個節點,所以當該節點的位置改變曲線適應它時?

謝謝。

回答

18

我認爲JavaFX中的CubicCurves並不像你認爲的那樣工作。一個JavaFX CubicCurve是一個Bezier curve,它與你在高中數學中通常遇到的三次多項式y = x^3完全不同。你從來不想知道的關於貝塞爾曲線的一切是here

貝塞爾曲線通常用於生成計算機圖形中的平滑曲線。它們由起點和終點以及一組控制點來定義曲線。您可以通過使用交互式示例進行演示,從而在拖動開始點,結束點和控制點以形成不同的曲線時最好地瞭解它的工作原理。

如何繪製例如:y = x^3?

雖然有可能解決貝塞爾方程減少到一個多項式如Y = X^3,你可能要問上math.stackexchange.com這個問題,其中數學家的口徑將是遠遠高於例如,我。

是否有可能將曲線的其中一個端點連接到另一個節點,所以當該節點的位置改變曲線適應它時?

是的,請嘗試下面的示例應用程序,其中曲線末端和控制點綁定到可拖動節點。曲線適應錨節點位置的變化,因爲它們被拖動。

import javafx.application.Application; 
import javafx.beans.property.DoubleProperty; 
import javafx.event.EventHandler; 
import javafx.scene.*; 
import javafx.scene.input.MouseEvent; 
import javafx.scene.paint.Color; 
import javafx.scene.shape.*; 
import javafx.stage.Stage; 

/** Example of how a cubic curve works, drag the anchors around to change the curve. */ 
public class CubicCurveManipulator extends Application { 
    public static void main(String[] args) throws Exception { launch(args); } 
    @Override public void start(final Stage stage) throws Exception { 
    CubicCurve curve = createStartingCurve(); 

    Line controlLine1 = new BoundLine(curve.controlX1Property(), curve.controlY1Property(), curve.startXProperty(), curve.startYProperty()); 
    Line controlLine2 = new BoundLine(curve.controlX2Property(), curve.controlY2Property(), curve.endXProperty(), curve.endYProperty()); 

    Anchor start = new Anchor(Color.PALEGREEN, curve.startXProperty(), curve.startYProperty()); 
    Anchor control1 = new Anchor(Color.GOLD,  curve.controlX1Property(), curve.controlY1Property()); 
    Anchor control2 = new Anchor(Color.GOLDENROD, curve.controlX2Property(), curve.controlY2Property()); 
    Anchor end  = new Anchor(Color.TOMATO, curve.endXProperty(),  curve.endYProperty()); 

    stage.setTitle("Cubic Curve Manipulation Sample"); 
    stage.setScene(new Scene(new Group(controlLine1, controlLine2, curve, start, control1, control2, end), 400, 400, Color.ALICEBLUE)); 
    stage.show(); 
    } 

    private CubicCurve createStartingCurve() { 
    CubicCurve curve = new CubicCurve(); 
    curve.setStartX(100); 
    curve.setStartY(100); 
    curve.setControlX1(150); 
    curve.setControlY1(50); 
    curve.setControlX2(250); 
    curve.setControlY2(150); 
    curve.setEndX(300); 
    curve.setEndY(100); 
    curve.setStroke(Color.FORESTGREEN); 
    curve.setStrokeWidth(4); 
    curve.setStrokeLineCap(StrokeLineCap.ROUND); 
    curve.setFill(Color.CORNSILK.deriveColor(0, 1.2, 1, 0.6)); 
    return curve; 
    } 

    class BoundLine extends Line { 
    BoundLine(DoubleProperty startX, DoubleProperty startY, DoubleProperty endX, DoubleProperty endY) { 
     startXProperty().bind(startX); 
     startYProperty().bind(startY); 
     endXProperty().bind(endX); 
     endYProperty().bind(endY); 
     setStrokeWidth(2); 
     setStroke(Color.GRAY.deriveColor(0, 1, 1, 0.5)); 
     setStrokeLineCap(StrokeLineCap.BUTT); 
     getStrokeDashArray().setAll(10.0, 5.0); 
    } 
    } 

    // a draggable anchor displayed around a point. 
    class Anchor extends Circle { 
    Anchor(Color color, DoubleProperty x, DoubleProperty y) { 
     super(x.get(), y.get(), 10); 
     setFill(color.deriveColor(1, 1, 1, 0.5)); 
     setStroke(color); 
     setStrokeWidth(2); 
     setStrokeType(StrokeType.OUTSIDE); 

     x.bind(centerXProperty()); 
     y.bind(centerYProperty()); 
     enableDrag(); 
    } 

    // make a node movable by dragging it around with the mouse. 
    private void enableDrag() { 
     final Delta dragDelta = new Delta(); 
     setOnMousePressed(new EventHandler<MouseEvent>() { 
     @Override public void handle(MouseEvent mouseEvent) { 
      // record a delta distance for the drag and drop operation. 
      dragDelta.x = getCenterX() - mouseEvent.getX(); 
      dragDelta.y = getCenterY() - mouseEvent.getY(); 
      getScene().setCursor(Cursor.MOVE); 
     } 
     }); 
     setOnMouseReleased(new EventHandler<MouseEvent>() { 
     @Override public void handle(MouseEvent mouseEvent) { 
      getScene().setCursor(Cursor.HAND); 
     } 
     }); 
     setOnMouseDragged(new EventHandler<MouseEvent>() { 
     @Override public void handle(MouseEvent mouseEvent) { 
      double newX = mouseEvent.getX() + dragDelta.x; 
      if (newX > 0 && newX < getScene().getWidth()) { 
      setCenterX(newX); 
      } 
      double newY = mouseEvent.getY() + dragDelta.y; 
      if (newY > 0 && newY < getScene().getHeight()) { 
      setCenterY(newY); 
      } 
     } 
     }); 
     setOnMouseEntered(new EventHandler<MouseEvent>() { 
     @Override public void handle(MouseEvent mouseEvent) { 
      if (!mouseEvent.isPrimaryButtonDown()) { 
      getScene().setCursor(Cursor.HAND); 
      } 
     } 
     }); 
     setOnMouseExited(new EventHandler<MouseEvent>() { 
     @Override public void handle(MouseEvent mouseEvent) { 
      if (!mouseEvent.isPrimaryButtonDown()) { 
      getScene().setCursor(Cursor.DEFAULT); 
      } 
     } 
     }); 
    } 

    // records relative x and y co-ordinates. 
    private class Delta { double x, y; } 
    } 
} 

示例程序輸出:

cubiccurve sample program output

+1

謝謝,雖然我還沒有能夠解決這個問題,這是一個偉大的答覆,我差點忘了,計算器數學存在... – user1479589