问题
Is it possible to find the intersection points of two series in JFreeChart? The chart series that are intersecting don't have any common points among them. So, the intersection point needs to be calculated for two series that happens to intersect each other on the graph.
List<Line> lineOne = one.getItems();
List<Line> lineTwo = two.getItems();
for (Line i : lineOne) {
for (Line j : lineTwo) {
if (i.intersection(j) != null) {
System.out.println(i.intersection(j));
}
}
}
The code above is what I was trying to do, but this throws a ClassCastException with this message:
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException:
org.jfree.data.xy.XYDataItem cannot be cast to
org.apache.commons.math3.geometry.euclidean.twod.Line
After Trashgod's suggestion I have tried doing the following:
List<XYDataItem> l1 = one.getItems();
List<XYDataItem> l2 = two.getItems();
Line itemOne = null;
Line itemTwo = null;
List<Line> lineOne = new ArrayList<Line>();
List<Line> lineTwo = new ArrayList<Line>();
//Add lines to the first list
for(int i = 0; i < l1.size(); i++){
if(i < l1.size()-1) {
itemOne = new Line(new Vector2D(l1.get(i).getXValue(),
l1.get(i).getYValue()),
new Vector2D(l1.get(i+1).getXValue(),
l1.get(i+1).getYValue()), 0);
lineOne.add(itemOne);
}
}
//Add lines to the second list
for(int i = 0; i < l2.size(); i++){
if(i < l2.size()-1) {
itemTwo = new Line(new Vector2D(l2.get(i).getXValue(),
l2.get(i).getYValue()),
new Vector2D(l2.get(i+1).getXValue(),
l2.get(i+1).getYValue()), 0);
lineTwo.add(itemTwo);
}
}
for(Line i: lineOne) {
for(Line j: lineTwo) {
if (i.intersection(j) != null) {
System.out.println(i.intersection(j));
}
}
}
However, while traversing through this list, it yields a lot of results (as shown in the image below) even if there are only few intersection points.
And the intersection points are not correct either.
Image showing results
And my chart looks like this: Image for Jfreechart
Please suggest the problem with this.
回答1:
Yes, you can iterate though the items comprising the Series. As a concrete example, an XYSeries has a List of XYDataItem internally. Because XYDataItem implements Comparable, you can test for intersection using equals(). Given two series containing a single item in common,
private final XYSeries one = new XYSeries("One");
private final XYSeries two = new XYSeries("Two");
…
one.add(1, 1);
one.add(1, 42);
two.add(1, 2);
two.add(1, 42);
The following iteration scheme finds the common point, [1.0, 42.0]:
List<XYDataItem> list1 = one.getItems();
List<XYDataItem> list2 = two.getItems();
for (XYDataItem i : list1) {
for (XYDataItem j : list2) {
if (i.equals(j)) {
System.out.println(i);
}
}
}
Alternatively, you can use functional operations:
list1.stream().forEach((i) -> {
list2.stream().filter((j) -> (i.equals(j))).forEach((item) -> {
System.out.println(i);
});
});
I need to find the intersection of two
XYLineChartseries which don't have common data points among them.
You can use the same iteration scheme on two instances of List<Line>; each list should contain the lines connecting consecutive points of the corresponding series. Replace equals() with a notional intersects() method. You can use line–line intersection; Line::intersection is a typical implementation.
The code above…throws a
ClassCastExceptionwith the message,
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException:
org.jfree.data.xy.XYDataItem cannot be cast to
org.apache.commons.math3.geometry.euclidean.twod.Line
That is expected; you'll have to traverse each List<XYDataItem> to create the corresponding List<Line>. The first Line will be bounded by points 1 and 2; the second Line by points 2 and 3, etc.
来源:https://stackoverflow.com/questions/43556019/intersection-points-of-series