问题
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
XYLineChart
series 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
ClassCastException
with 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