我有一个类“Vertex”包含双x,y。另一个类“Face”包含一个“Vertex”对象列表。相邻面共享相同的顶点。
目前,我正在为每个脸创建一个javafx.scene.shape.多边形,并将它们全部添加到我的场景中,看起来像这样:截图
现在我计划修改多边形,类似于:JavaFX modify polygons
问题是多边形不会保存对顶点对象的引用,而是保存双值。当我改变一个点的位置时,相邻多边形中的同一点仍在原来的位置。我如何将这些点相互链接?以及如何将更改保存回我的“脸”对象?
所要求的代码示例:pastebin.com/C3JHb2nM
创建顶点属性的x和y坐标。然后,您可以将侦听器添加到修改多边形点的属性中:
public class Vertex {
public DoubleProperty xProperty() {
...
}
public DoubleProperty yProperty() {
...
}
}
public class VertexListener implements InvalidationListerner {
private final Vertex vertex;
private final int firstIndex;
private final List<Double> points;
public VertexListener(Vertex vertex, Polygon polygon, int pointIndex) {
this.firstIndex = 2 * pointIndex;
this.vertex = vertex;
this.points = polygon.getPoints();
vertex.xProperty().addListener(this);
vertex.yProperty().addListener(this);
}
public void dispose() {
vertex.xProperty().removeListener(this);
vertex.yProperty().removeListener(this);
}
@Override
public void invalidated(Observable observable) {
double x = vertex.getX();
double y = vertex.getY();
points.set(firstIndex, x);
points.set(firstIndex+1, y);
}
}
这样,您只需要调整顶点中的属性值,侦听器就会添加所有事件面。。。
干得好。计算出的公共锚点位置,然后在移动一个锚点时调整所有公共锚点位置。
Anchor包含addCommon
函数,该函数添加一个对其通用的锚。common
变量存储所有公共锚点。然后,当调用handle
时,所有常见的x和y
位置也会改变。
另外,我建议你保留Faces
中的共同点。我已经创建了一个简单的方法来计算所有在该类中共享顶点的Faces。但是遵循MVC准则,你需要一个模型来提供所有必要的数据来创建图形用户界面。我建议Mesh、Face和Vertex应该提供所有必要的信息来创建图形用户界面,而不是作为双向街道。基本上,锚不应该以任何方式改变你的模型。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javafx.application.Application;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.scene.Cursor;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Polygon;
import javafx.scene.shape.StrokeType;
import javafx.stage.Stage;
public class Main extends Application {
public class Vertex {
private double x, y;
public Vertex(double x, double y) {
this.x = x;
this.y = y;
}
public Double[] getPoint() {
return new Double[]{x, y};
}
}
public class Face {
private List<Vertex> verts;
public Face(Vertex... verts) {
this.verts = new ArrayList<>(Arrays.asList(verts));
}
public Polygon getPolygon() {
Polygon polygon = new Polygon();
polygon.setFill(Color.GRAY);
polygon.setStroke(Color.BLACK);
for (Vertex vertex : verts) {
polygon.getPoints().addAll(vertex.getPoint());
}
return polygon;
}
public boolean containsVertex(Vertex ver) {
for (Vertex v : this.verts) {
if (v.x == ver.x && v.y == ver.y) {
return true;
}
}
return false;
}
}
public class Mesh {
private List<Vertex> verts = new ArrayList<Vertex>();
private List<Face> faces = new ArrayList<Face>();
private Map<Vertex, List<Face>> commonVertices = new HashMap<>();
public List<Polygon> getPolygons() {
List<Polygon> polygons = new ArrayList<Polygon>();
for (Face face : faces) {
polygons.add(face.getPolygon());
}
return polygons;
}
public Mesh() {
verts.add(new Vertex(50, 50));
verts.add(new Vertex(300, 50));
verts.add(new Vertex(500, 50));
verts.add(new Vertex(50, 300));
verts.add(new Vertex(250, 300));
verts.add(new Vertex(500, 300));
verts.add(new Vertex(50, 600));
verts.add(new Vertex(300, 700));
verts.add(new Vertex(500, 700));
faces.add(new Face(verts.get(0), verts.get(1), verts.get(4), verts.get(3)));
faces.add(new Face(verts.get(4), verts.get(1), verts.get(2), verts.get(5)));
faces.add(new Face(verts.get(3), verts.get(4), verts.get(7), verts.get(6)));
faces.add(new Face(verts.get(7), verts.get(4), verts.get(5)));
faces.add(new Face(verts.get(7), verts.get(5), verts.get(8)));
findCommonVertices();
}
private void findCommonVertices() {
for (Vertex ver : this.verts) {
List<Face> share = new ArrayList<>();
for (Face face : this.faces) {
if (face.containsVertex(ver)) {
share.add(face);
}
}
commonVertices.put(ver, share);
}
}
public Map<Vertex, List<Face>> getCommonVertices() {
return this.commonVertices;
}
}
@Override
public void start(Stage stage) {
Group root = new Group();
Scene scene = new Scene(root, 1024, 768);
stage.setScene(scene);
Group g = new Group();
Mesh mesh = new Mesh();
List<Polygon> polygons = mesh.getPolygons();
g.getChildren().addAll(polygons);
List<Anchor> anchors = new ArrayList<>();
for (Polygon p : polygons) {
ObservableList<Anchor> temp = createControlAnchorsFor(p.getPoints());
g.getChildren().addAll(temp);
for (Anchor kk : temp) {
anchors.add(kk);
}
}
for (int i = 0; i < anchors.size(); i++) {
List<Anchor> common = new ArrayList<>();
for (int j = 0; j < anchors.size(); j++) {
if (i != j) {
if (anchors.get(i).x.doubleValue() == anchors.get(j).x.doubleValue() && anchors.get(i).y.doubleValue() == anchors.get(j).y.doubleValue()) {
anchors.get(i).addCommon(anchors.get(j));
System.out.println("COMMON " + i + " " + j);
}
}
}
// anchors.get(i).setCommon(common);
}
scene.setRoot(g);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
// Everything below was copied from here: https://gist.github.com/jewelsea/5375786
// @return a list of anchors which can be dragged around to modify points in the format [x1, y1, x2, y2...]
private ObservableList<Anchor> createControlAnchorsFor(final ObservableList<Double> points) {
ObservableList<Anchor> anchors = FXCollections.observableArrayList();
for (int i = 0; i < points.size(); i += 2) {
final int idx = i;
DoubleProperty xProperty = new SimpleDoubleProperty(points.get(i));
DoubleProperty yProperty = new SimpleDoubleProperty(points.get(i + 1));
xProperty.addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> ov, Number oldX, Number x) {
points.set(idx, (double) x);
}
});
yProperty.addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> ov, Number oldY, Number y) {
points.set(idx + 1, (double) y);
}
});
anchors.add(new Anchor(Color.GOLD, xProperty, yProperty));
}
return anchors;
}
// a draggable anchor displayed around a point.
class Anchor extends Circle {
private final DoubleProperty x, y;
List<Anchor> common = new ArrayList<>();
public void setCommon(List<Anchor> common) {
this.common = common;
}
public void addCommon(Anchor com) {
common.add(com);
enableDrag();
}
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);
this.x = x;
this.y = y;
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);
if (common != null) {
for (Anchor an : common) {
an.setCenterX(newX);
System.out.println("CALLED");
}
}
}
double newY = mouseEvent.getY() + dragDelta.y;
if (newY > 0 && newY < getScene().getHeight()) {
setCenterY(newY);
if (common != null) {
for (Anchor an : common) {
an.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;
}
}
}
主要内容:JavaFX多边形折线JavaFX多边形折线 多边形,一个简单的示例代码如下所示 - 上面的代码生成以下结果。 折线示例,一个简单的示例代码如下所示 - 上面的代码生成以下结果。
有没有办法在JavaFX中修改多边形?例如,如果我有一个三角形,我按下然后从该三角形拖动一个点,三角形将用该点的新坐标进行修改。
我目前正在使用JavaFX研究不同形状之间的边界相交。我想检测两个多边形在它们的点上的碰撞,而不是在它们的边界上(即2个多边形)。 请参阅图1:不期望的行为,以及图2:期望的行为。 是否有任何现有的算法可以帮助我或使用任何库?提前感谢:) 在这里找到我的解决方案: 输出: 它似乎工作正常,我将使用Path对象进行测试以替换多边形objets。
返回顶点的输入数组,并且附有一些其他方法,如下面所描述 polygon.area() 返回此多边形的标定区域。如果顶点是逆时针顺序,面积为正,否则为负。 polygon.centroid() 返回一个表示此多边形的质心的两元素数组。 polygon.clip(subject) 对这个多边形剪切主题多边形。换句话说,返回一个多边形表示这个多边形和主题多边形的交集。假定剪切的多边形是逆时针方向以及凸多
基础示例 <vuep template="#example"></vuep> <script v-pre type="text/x-template" id="example"> <template> <div class="amap-page-container"> <el-amap vid="amap" :zoom="zoom" :amap-manager="ama
SVG 多边形 - <polygon> 实例 1 <polygon> 标签用来创建含有不少于三个边的图形。 多边形是由直线组成,其形状是"封闭"的(所有的线条 连接起来)。 polygon来自希腊。 "Poly" 意味 "many" , "gon" 意味 "angle". 下面是SVG代码: <svg xmlns="http://www.w3.org/2000/svg" version="1.1"