提问人:FarHooD 提问时间:10/23/2023 最后编辑:FarHooD 更新时间:10/24/2023 访问量:77
Javafx:用角度拉近两点
Javafx: Bringing two points closer to each other with angle
问:
您好,所有 Stackoverflow 用户,我有多边形形状(或三角形),我需要在它的侧中心添加一些标签,想象一下我有框架,如果剪辑形状从中删除其他区域,问题是如果剪辑我的 GraphicContext 的标签将从我创建的形状中删除,为了说出我遇到的问题,我希望标签靠近形状中心,有一些间隙我添加了它(如 24px 72px 等),但我发现如果我想这样做,需要调整角度并将比例添加到间隙中以封闭到中心,但我不知道该怎么做?我的数学很差:))谁能给我小费?
我添加的形状只是我需要的示例,而我向您展示的代码只是一些肮脏的工作。
private int[] pointLocateForExportLabel(Point2D a1, Point2D a2, Point2D centerPoint, int fontMetric) {
int gapIntoShape = (int) (fontMetric) * 9;
App.logger.debug("The Center point : " + centerPoint);
App.logger.debug("The A1 of point : " + a1);
App.logger.debug("The A2 of point : " + a2);
App.logger.debug("==============================");
int poX = (int) (((a1.getX() + a2.getX()) / 2));
int poY = (int) (((a1.getY() + a2.getY()) / 2));
Point c1 = new Point(poX, poY);
double deltaX = centerPoint.getX() - c1.getX();
double deltaY = centerPoint.getY() - c1.getY();
double coeff = 0.05;
Point2D c = null;
if (centerPoint.getX() > c1.getX()) {
c = new Point2D(c1.getX() + coeff * deltaX, c1.getY() + coeff * deltaY);
} else {
c = new Point2D((c1.getX() + coeff * deltaX) - gapIntoShape, c1.getY() + coeff * deltaY);
}
return new int[]{(int) c.getX(), (int) c.getY()};
}
更新: 为了更好地理解,我需要将接近点带入接近另一个点!但不是两个方向(x 和 y)的一个方向(只是 x 或 y),这是一个简单的问题,IDK 如何太固定了。
答:
这在 StackExchange 上的 Mathmatics 上可能会更好。
但我认为这就是如何做到的(仅适用于等边三角形)
计算多边形的中点:您可以将中点计算为所有顶点的平均值
计算文本的绘制点:这很棘手,因为线条的起点取决于 FontMetrics 的高度。将文本放入空间取决于 FontMetrics.charWidth。因此,我认为它的计算是一个微分方程(或者你可以进行测试并迭代调整)
老实说,这是一个非常棘手的问题,仅适用于这种独特的形状。这对你来说值得吗?
同样,我建议你试试数学,看看他们是否有更好的答案。
评论
Point2D
类提供所需的所有矢量功能。给定,你可以做到Point2D start
Point2D center
Point2D needed = center.add(start.subtract(center).multiply(coeff));
Point2D
类实现了许多基本的向量代数运算。
在数学上,if 和 是点,则表示从 到 的向量。对于标量,a
b
b-a
a
b
t
a + t(b-a) = (1-t)a + tb
表示直线上经过 和 的点(直观地说,从 开始并将向量的倍数从 移动到 )。当 和 当 , .a
b
a
a
b
t=0
(1-t)a +tb = a
t=1
(1-t)a + tb = b
在本例中,是线的中心点,是形状的中心,并且是您在代码中调用的值。a
b
t
coeff
因此,在 Java 代码中,它看起来像:
Point2D centerLine = new Point2D(...) ;
Point2D centerShape = new Point2D(...) ;
Point2D requiredPoint = centerLine.multiply(1-coeff).add(centerShape.multiply(coeff));
如前所述,您可以简单地将线的中心作为端点的平均值,将形状的中心作为顶点的平均值。
下面是一个演示:
package com.example.vectors;
import javafx.application.Application;
import javafx.geometry.Point2D;
import javafx.scene.Scene;
import javafx.scene.control.Slider;
import javafx.scene.control.Spinner;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Polyline;
import javafx.stage.Stage;
import java.io.IOException;
public class HelloApplication extends Application {
private Point2D centerLine ;
private Point2D centerShape;
private Circle point = new Circle(5);
@Override
public void start(Stage stage) throws IOException {
Spinner<Integer> numVertexesSpinner = new Spinner<>(3, 10, 5);
Slider pointSlider = new Slider(0, 1, 0.5);
VBox controls = new VBox(5, numVertexesSpinner, pointSlider);
Pane drawingPane = new Pane();
drawingPane.setPrefSize(420, 420);
drawShapes(numVertexesSpinner.getValue(), pointSlider.getValue(), drawingPane);
BorderPane root = new BorderPane();
root.setTop(controls);
root.setCenter(drawingPane);
numVertexesSpinner.valueProperty().addListener((obs, oldValue, newValue) ->
drawShapes(newValue, pointSlider.getValue(), drawingPane)
);
pointSlider.valueProperty().addListener((obs, oldValues, newValue) -> updatePoint(newValue.doubleValue()));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
private void drawShapes(int numVertexes, double pointPos, Pane pane) {
pane.getChildren().clear();
final double radius = 200 ;
Point2D[] vertexes = new Point2D[numVertexes];
double[] coords = new double[numVertexes * 2 + 2];
for (int i = 0 ; i<vertexes.length; i++) {
double angle = 2 * Math.PI * i / numVertexes;
double x = radius + radius * Math.cos(angle);
double y = radius + radius * Math.sin(angle);
vertexes[i] = new Point2D(x, y);
coords[2*i] = x ;
coords[2*i+1] = y ;
}
coords[numVertexes * 2] = coords[0];
coords[numVertexes * 2 + 1] = coords[1];
Polyline poly = new Polyline(coords);
pane.getChildren().add(poly);
centerLine = vertexes[0].add((vertexes[1])).multiply(0.5);
centerShape = new Point2D(0,0);
for (Point2D vertex : vertexes) {
centerShape = centerShape.add(vertex);
}
centerShape = centerShape.multiply(1.0 / numVertexes);
pane.getChildren().addAll(new Circle(centerLine.getX(), centerLine.getY(), 5));
pane.getChildren().addAll(new Circle(centerShape.getX(), centerShape.getY(), 5));
pane.getChildren().add(point);
updatePoint(pointPos);
}
private void updatePoint(double pointPos) {
Point2D pos = centerLine.multiply(1-pointPos).add(centerShape.multiply(pointPos));
point.setCenterX(pos.getX());
point.setCenterY(pos.getY());
}
public static void main(String[] args) {
launch();
}
}
下一个:如何从浮点数中获取地图值
评论