I need a little help with java.
I need to create some curves between two points.
Application needs to create a random number of curves that will
connect from random generated begin point to random generated end point.
Here is my code so far:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package tryproject;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.QuadCurve2D;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;
import javax.swing.JPanel;
/**
*
* #author Q
*/
public class GUI extends JPanel{
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
ArrayList<Point> jaa = new ArrayList<Point>();
Random ja = new Random();
Random p = new Random();
int x = ja.nextInt(50) +50;
int y = ja.nextInt(150) + 150;
Point pocetnaTacka = new Point(Math.abs(ja.nextInt(150)),Math.abs(ja.nextInt(150)));
Point zavrsmaTacka = new Point(Math.abs(ja.nextInt(300) ) ,Math.abs(ja.nextInt(300)));
int lx = pocetnaTacka.x;
int ly = pocetnaTacka.y;
jaa.add(pocetnaTacka);
int rastojanje = (pocetnaTacka.x - zavrsmaTacka.x)/10;
for (int i = 1;i< Math.abs(ja.nextInt(8));i++){
x = lx + Math.abs(ja.nextInt(50));
y = ly + Math.abs(ja.nextInt(50));
jaa.add(new Point(x,y));
lx = x;
ly = y;
}
Graphics2D g2 = (Graphics2D) g;
RenderingHints rh = new RenderingHints(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHints(rh);
jaa.add(zavrsmaTacka);
Point lastpp = (Point)pocetnaTacka.clone();
for(Point pp: jaa)
{
QuadCurve2D q = new QuadCurve2D.Float();
// draw QuadCurve2D.Float with set coordinates
q.setCurve(lastpp.x, lastpp.y, pp.x/3, pp.y/3, pp.x, pp.y);
g2.draw(q);
lastpp = (Point) pp.clone();
}
for(Point aa: jaa)
{
System.out.println(aa.x + " , "+aa.y);
}
}
}
This is how it should look but i cant get it like this:
http://www.dodaj.rs/f/2U/qT/4LubxcQN/everytime.png
And every time application runs Two new point will be generated and curves to ..
I tried with sin , cos functions but i can't get it to work between two point.
Can anybody help me .
Thanks in advance.
I solved this problem. :
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package tryproject2;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.geom.QuadCurve2D;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JPanel;
/**
*
* #author Q
*/
public class GUI extends JPanel {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
ArrayList<Point> jaa = new ArrayList<Point>();
Random pocetnaikrajnja = new Random();
RenderingHints rh = new RenderingHints(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHints(rh);
g2.setColor(Color.BLUE);
Point pocetnaTacka = new Point(Math.abs(pocetnaikrajnja.nextInt(150)), Math.abs(pocetnaikrajnja.nextInt(200) + 100));
g2.fillOval(pocetnaTacka.x,pocetnaTacka.y, 5, 5);
jaa.add(pocetnaTacka);
Point poslednjatacka = (Point) pocetnaTacka.clone();
for (int i = 1;i< 6;i++){
Point p = new Point(poslednjatacka.x + Math.abs(pocetnaikrajnja.nextInt(30) + 30),pocetnaTacka.y - Math.abs(pocetnaikrajnja.nextInt(30) + 30));
poslednjatacka = p;
jaa.add(p);
}
Point zavrsnaTacka = null;
zavrsnaTacka = new Point(jaa.get(jaa.size()-1).x+Math.abs(pocetnaikrajnja.nextInt(15) + 15),jaa.get(jaa.size()-1).y-70);
jaa.add(zavrsnaTacka);
g2.setColor(Color.RED);
g2.fillOval(zavrsnaTacka.x,zavrsnaTacka.y, 5, 5);
for(int i=0;i<jaa.size()-1;i++)
{
QuadCurve2D q = new QuadCurve2D.Float();
//if(i%2==0){
q.setCurve(jaa.get(i).x, jaa.get(i).y,jaa.get(i).x/1.2,jaa.get(i).y-Math.abs(pocetnaikrajnja.nextInt(35) + 35), jaa.get(i+1).x, jaa.get(i+1).y);
//}
//else
//{
// q.setCurve(jaa.get(i).x, jaa.get(i).y,jaa.get(i).x/1.2,jaa.get(i).y+Math.abs(pocetnaikrajnja.nextInt(35) + 35), jaa.get(i+1).x, jaa.get(i+1).y);
//}
g2.draw(q);
}
/**
* Sakriven kod za grane.
for(int i=1;i<jaa.size()-Math.abs(pocetnaikrajnja.nextInt(2)+1);i= i + Math.abs(pocetnaikrajnja.nextInt(5)))
{
QuadCurve2D q = new QuadCurve2D.Float();
if(i%2==0)
q.setCurve(jaa.get(i).x, jaa.get(i).y,jaa.get(i).x/1.2,jaa.get(i).y/1.2, jaa.get(i).x + Math.abs(pocetnaikrajnja.nextInt(5) + 7), jaa.get(i).y - Math.abs(pocetnaikrajnja.nextInt(10) + 60));
else
q.setCurve(jaa.get(i).x, jaa.get(i).y,jaa.get(i).x/1.2,jaa.get(i).y/1.2, jaa.get(i).x + Math.abs(pocetnaikrajnja.nextInt(5) + 7), jaa.get(i).y + Math.abs(pocetnaikrajnja.nextInt(10) + 60));
g2.draw(q);
}
*/
}
}
Related
I am trying to map a zero indexed value to a multidimensional array list using the map function so that I can assign data to specific values within the arraylist without having to constantly request that I Dex location. The code I have written is not compiling for some reason.
Could so eone please check it their side please and also criticise where required?
`
package main.java.javatestfiles;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* #####CORRECTED#####
*
* The purpose of the class is to map a cubic calculation to
* a multidimensional arraylist as the partials iterate over
* the cubic sum of n in the key to value mappings.
*
* Help from : https://www.javatpoint.com/java-map
*
* #author devel
*/
public class Cubic_Mapping_2 {
public static void main(String[] args) {
int j, k, l, i;
double n = 4.0;
double v = Math.pow(n, 3.0);
ArrayList<ArrayList<ArrayList<Integer>>> c = new ArrayList<>();
Map map = new HashMap();
for (j = 0; j <= v-1; j++) {
for (k = 0; k <= n; k++) {
for(l = 0; l <= n; l++) {
for (i = 0; i <= n; i++) {
map.put(c.get(k).get(l).get(i), j);
}
}
}
}
Set set = map.entrySet(); //Converting to Set so that we can traverse
Iterator itr = set.iterator();
while(itr.hasNext()){
//Converting to Map.Entry so that we can get key and value
Map.Entry entry = (Map.Entry) itr.next();
System.out.println(entry.getKey() + " " + entry.getValue());
}
}
}
`
Thank you, look forward to hearing from you.
R
Tried swapping the key and value variables around, <int, arraylist> and tried calling c variable as an output to check content, however that will not work because there is no content it is a mapping schema.
There does not seem to be any error message on compile in VSCode however in eclipse just a generic exception for 0 index.
################################################################
I wrote a new solution -
`
package javatestfiles;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
/**
* The purpose of the class is to map a cubic calculation to
* a multidimensional ArrayList as the partials iterate over
* the cubic sum of n in the key to value mappings.
*
* Help from : https://www.javatpoint.com/java-map
* https://www.baeldung.com/java-multi-dimensional-arraylist
* https://www.w3schools.com/java/java_hashmap.asp
* https://www.geeksforgeeks.org/java-util-hashmap-in-java-with-examples/
*
* #author devel
*/
public class Cubic_Mapping_3 {
static Map<Integer, Object> map = new HashMap<>();
static ArrayList<ArrayList<ArrayList<Object>>> c;
/**
* Populate an ArrayList with n indices cubed.
*
* #param n
* #return Three dimensional ArrayList c
*/
public static ArrayList<ArrayList<ArrayList<Object>>> three_d_list(int n) {
int i, j;
int x_axis = n;
int y_axis = n;
int z_axis = n;
ArrayList<ArrayList<ArrayList<Object>>> c = new ArrayList<>(x_axis);
for (i = 0; i <= x_axis; i++) {
c.add(new ArrayList<ArrayList<Object>>(z_axis));
for (j = 0; j < z_axis; j++) {
c.get(i).add(new ArrayList<Object>(y_axis));
}
}
return c;
}
/**
* Randomly populate the mapped volumetrics with Neurons
* #param neuron
* #param qty - Quantity of neurons
* #param v - Received autonomously from mapping()
*/
public static void populate(Object neuron, int qty, double v) {
Random rand = new Random();
int i;
for (i = 0; i <= qty; i++) {
map.put(rand.nextInt((int) v), neuron);
}
}
/**
* Maps the cubic index length to the ArrayList c and calls the populate()
* autonomously to populate the list and the mapping with the Neurons
*
* #param neuron - An Objectified ArrayList comprising the AI and areas / proximities
* #param qty - The quantity of Neurons to deploy randomly in your mapped volumetrics
* #param n - The index to be used to calculate the cubic size of the volume
*/
public static void mapping(ArrayList<Object> neuron, int qty, int n) {
int j, k, l, i;
double v = Math.pow(n, 3);
ArrayList<ArrayList<ArrayList<Object>>> c = three_d_list(n);
for (j = 0; j < n; j++) {
for (k = 0; k < n; k++) {
for(l = 0; l < n; l++) {
c.get(j).get(k).add(l);
for (i = 0; i < v; i++) {
map.put(i, c.get(j).get(k).get(l));
}
}
}
}
populate(neuron, qty, v);
}
/**
* Clear the data in memory store after use.
*/
public static void clearall() {
map.clear();
c.clear();
}
public static Map<Integer, Object> main(String[] args) {
mapping(null, 0, 0); //Entry point, the autonomy does the rest.
return map;
}
}
`
I am creating a 3D plot in JavaFX using the same technique discussed in this answer, with a MeshView and a PhongMaterial to provide the colours. However, only the top side of the material is coloured, and if the user rotates the camera to view from below, it's impossible to determine the shape of the plot because it is all black.
My questions:
Is there any way to set the material of the reverse side of the mesh?
If not, is there a good approach to "faking" it? I would imagine creating a new mesh upside-down in exactly the same position would cause rendering issues; is the best approach to do that but apply a very small offset so that the two meshes are not exactly on top of each other?
Edit: I have included some example code below, which is cut down from my real code but contains enough to illustrate the problem. By default it displays the top of the mesh, which is coloured red in this example. If you change the line that reads new Rotate(-30, Rotate.X_AXIS) so that the angle becomes +30 rather than -30, it will rotate the camera to show the underside of the mesh, which you will see appears black.
package test;
import javafx.application.Application;
import javafx.scene.DepthTest;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.SceneAntialiasing;
import javafx.scene.SubScene;
import javafx.scene.image.Image;
import javafx.scene.image.PixelWriter;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.CullFace;
import javafx.scene.shape.DrawMode;
import javafx.scene.shape.MeshView;
import javafx.scene.shape.TriangleMesh;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Translate;
import javafx.stage.Stage;
public class TestApp extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) throws Exception {
TestPlot tp = new TestPlot();
tp.setPrefSize(600, 400);
Scene scene = new Scene(tp);
stage.setScene(scene);
stage.show();
}
class TestPlot extends Region {
private final PerspectiveCamera camera = new PerspectiveCamera(true);
private double[][] data = new double[500][500];
private final StackPane root = new StackPane();
private final SubScene subscene;
public TestPlot() {
subscene = new SubScene(root, 1, 1, true, SceneAntialiasing.BALANCED);
subscene.setCamera(camera);
getChildren().add(subscene);
widthProperty().addListener((obs, oldVal, newVal) -> refreshPlot());
heightProperty().addListener((obs, oldVal, newVal) -> refreshPlot());
refreshPlot();
}
private void refreshPlot() {
// Set the subscene bounds to match the plot bounds, in case the plot was
// resized
subscene.setHeight(this.getHeight());
subscene.setWidth(this.getWidth());
// Clear any existing stuff
root.getChildren().clear();
root.setStyle("-fx-background-color: rgba(0, 0, 0, 0);");
root.getChildren().add(camera);
camera.getTransforms().clear();
int xDataPoints = data.length;
int zDataPoints = data[0].length;
// Create data mesh
TriangleMesh mesh = new TriangleMesh();
for (int x = 0; x < xDataPoints; x++) {
for (int z = 0; z < zDataPoints; z++) {
// Invert the data as JavaFX meshes are positive-down, whereas we expect
// the plot to be positive-up
mesh.getPoints().addAll(x, (float) (-data[x][z]), z);
}
}
// Create faces from data mesh
for (int x = 0; x < xDataPoints - 1; x++) {
for (int z = 0; z < zDataPoints - 1; z++) {
int tl = x * zDataPoints + z; // top-left
int bl = x * zDataPoints + z + 1; // bottom-left
int tr = (x + 1) * zDataPoints + z; // top-right
int br = (x + 1) * zDataPoints + z + 1; // bottom-right
int offset = (x * (zDataPoints - 1) + z) * 8 / 2; // div 2 because we have u AND v in the list
// working
mesh.getFaces().addAll(bl, offset + 1, tl, offset + 0, tr, offset + 2);
mesh.getFaces().addAll(tr, offset + 2, br, offset + 3, bl, offset + 1);
}
}
// Create data mesh texture map
for (float x = 0; x < xDataPoints - 1; x++) {
for (float z = 0; z < zDataPoints - 1; z++) {
float x0 = x / xDataPoints;
float z0 = z / zDataPoints;
float x1 = (x + 1) / xDataPoints;
float z1 = (z + 1) / zDataPoints;
mesh.getTexCoords().addAll( //
x0, z0, // 0, top-left
x0, z1, // 1, bottom-left
x1, z1, // 2, top-right
x1, z1 // 3, bottom-right
);
}
}
// Create texture material
Image diffuseMap = createTexture(data);
PhongMaterial material = new PhongMaterial();
material.setDiffuseMap(diffuseMap);
// Create & add mesh view
MeshView meshView = new MeshView(mesh);
meshView.setTranslateZ(-zDataPoints);
meshView.setMaterial(material);
meshView.setCullFace(CullFace.NONE);
meshView.setDrawMode(DrawMode.FILL);
meshView.setDepthTest(DepthTest.ENABLE);
root.getChildren().addAll(meshView);
double biggestAxisSize = xDataPoints;
double z = -(0.5 * biggestAxisSize) / Math.tan(0.5 * Math.toRadians(camera.getFieldOfView()));
camera.getTransforms().addAll(
new Translate(0, 0, -zDataPoints / 3.0),
new Rotate(-30, Rotate.X_AXIS),
new Translate(0, 0.5, z)
);
camera.setFarClip(biggestAxisSize * 200.0);
}
private Image createTexture(double[][] data) {
int width = data.length;
int height = data[0].length;
WritableImage wr = new WritableImage(width, height);
PixelWriter pw = wr.getPixelWriter();
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
pw.setColor(x, y, Color.RED);
}
}
return wr;
}
}
}
Modify the cullFace property of your MeshView:
meshView.setCullFace(CullFace.NONE);
Also you need to add ambient light to the scene. The normals of the surface are automatiacally determined and the scalar product used with won't be positive, if the normal is facing away from the light source...
root.getChildren().add(new AmbientLight(Color.WHITE));
This is my code :
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Polygon;
import javafx.stage.Stage;
import org.nocrala.tools.gis.data.esri.shapefile.ShapeFileReader;
import org.nocrala.tools.gis.data.esri.shapefile.ValidationPreferences;
import org.nocrala.tools.gis.data.esri.shapefile.exception.InvalidShapeFileException;
import org.nocrala.tools.gis.data.esri.shapefile.header.ShapeFileHeader;
import org.nocrala.tools.gis.data.esri.shapefile.shape.AbstractShape;
import org.nocrala.tools.gis.data.esri.shapefile.shape.PointData;
import org.nocrala.tools.gis.data.esri.shapefile.shape.shapes.PolygonShape;
public class MakeMap extends Application
{
static FileInputStream is;
static ShapeFileReader read;
static ShapeFileHeader head;
static AbstractShape shape;
static ValidationPreferences prefs;
static double minLat;
static double minLon;
static double maxLat;
static double maxLon;
static double ratio;
static double bMinLat;
static double bMinLon;
static double bMaxLat;
static double bMaxLon;
int gapx = 0, gapy = 0;
public void makeRatio(double lon_max, double lon_min, double lat_max, double lat_min)
{
double x, y; x = lon_max - lon_min;
y = lat_max - lat_min;
x = 600 / x;
y = 600 / y; if (x < y)
{
ratio = x;
gapy = (int) ((600 - (lat_max - lat_min) * x) / 2);
} else {
ratio = y; gapx = (int) ((600 - (lon_max - lon_min) * y) / 2); } }
public void assignBoundary(double min_lon, double max_lon, double min_lat, double max_lat)
{
minLon = coActLon(min_lon) * ratio; maxLon = coActLon(max_lon) * ratio; minLat = coActLat(min_lat) * ratio;
maxLat = coActLat(max_lat) * ratio;
}
public double coActLat(double p)
{
p = bMaxLat - p; return p;
}
public double coActLon(double p)
{
p = p - bMinLon; return p;
}
public int assignBoundaryLon(double p)
{
p = coActLon(p) * ratio - minLon; p += gapx;
return (int) p;
}
public int assignBoundaryLat(double p)
{
p = coActLat(p) * ratio;
p = p - maxLat; p += gapy;
return (int) p;
}
#Override public void start(Stage stage) throws Exception
{ File file = new File("/home/ranu/world.shp");
Canvas canvas = new Canvas(600, 600);
GraphicsContext gc = canvas.getGraphicsContext2D();
try
{
is = new FileInputStream(file);
}
catch (FileNotFoundException e)
{ // TODO Auto-generated catch block
e.printStackTrace();
} prefs = new ValidationPreferences();
prefs.setMaxNumberOfPointsPerShape(33200);
try
{
read = new ShapeFileReader(is, prefs);
}
catch (InvalidShapeFileException | IOException e)
{ // TODO Auto-generated catch block e.printStackTrace(); }
head = read.getHeader();
bMaxLon = head.getBoxMaxX();
bMinLon = head.getBoxMinX();
bMaxLat = head.getBoxMaxY();
bMinLat = head.getBoxMinY();
makeRatio(head.getBoxMaxX(), head.getBoxMinX(), head.getBoxMaxY(), head.getBoxMinY());
assignBoundary(head.getBoxMinX(), head.getBoxMaxX(), head.getBoxMinY(), head.getBoxMaxY());
gc.setFill(Color.rgb(53, 153, 255));
gc.fillRect(gapx, gapy, (maxLon - minLon), (minLat - maxLat));
drawShape(gc);
StackPane root = new StackPane();
root.getChildren().add(canvas);
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public void drawShape(GraphicsContext gc) throws IOException, InvalidShapeFileException
{
int i = 0; gc.setFill(Color.WHITE);
gc.setStroke(Color.LIGHTGREY); gc.setLineWidth(1);
gc.strokeLine(10, 20, 30, 40);
Polygon polygon = new Polygon();
polygon.getPoints().add(new Double(20.0));
int count = 0;
double[] lat;
double[] lon;
Double[] data; gc.setStroke(Color.LIGHTGRAY);
while ((shape = read.next()) != null && count < 360)
{ // System.out.println(shape);
switch (shape.getShapeType())
{
case POINT: // PointShape aPoint = (PointShape) shape;
// Do something with the point shape... break;
case MULTIPOINT_Z: // MultiPointZShape aMultiPointZ = (MultiPointZShape) shape;
// Do something with the MultiPointZ shape... break;
case POLYGON: PolygonShape aPolygon = (PolygonShape) shape;
lat = new double[aPolygon.getNumberOfPoints()];
lon = new double[aPolygon.getNumberOfPoints()];
data = new Double[aPolygon.getNumberOfPoints() * 2];
int j = 0;
double x, y;
PointData[] point = aPolygon.getPoints();
for (i = 0; i < aPolygon.getNumberOfPoints(); i++)
{
x = point[i].getX();
y = point[i].getY();
j = 0; lat[j] = this.assignBoundaryLat(point[i].getY());
lon[j] = this.assignBoundaryLon(point[i].getX());
// data[j++] = new // Double(this.assignBoundaryLon(point[i].getX()));
// data[j] = new // Double(this.assignBoundaryLon(point[i].getY()));
for (j = j + 1, i = i + 1; (x != point[i].getX() || y != point[i] .getY()) && i < aPolygon.getNumberOfPoints(); i++, j++)
{
// lat[j] = this.assignBoundaryLat(point[i].getY());
// lon[j] = this.assignBoundaryLon(point[i].getX());
// data[j++] = new // Double(this.assignBoundaryLat(point[i].getX()));
// data[j] = new // Double(this.assignBoundaryLat(point[i].getY())); }
System.out.println(lat.length + " " + lon.length + " " + j);
// Polygon pg = new Polygon();
// pg.getPoints().addAll(data);
gc.strokePolygon(lon, lat, j);
System.out.println(count);
count ++; }
break; default: break; } } }
public static void main(String[] args)
{ Application.launch(args); }
Problem have in this code :
130 130 129
0
514 514 513
Exception in Application start method
Exception in thread "main" java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:403)
at com.sun.javafx.application.LauncherImpl.access$000(LauncherImpl.java:47)
at com.sun.javafx.application.LauncherImpl$1.run(LauncherImpl.java:115)
at java.lang.Thread.run(Thread.java:724)
Caused by: java.lang.ArrayIndexOutOfBoundsException: 512
at javafx.scene.canvas.GraphicsContext.writePoly(GraphicsContext.java:326)
at javafx.scene.canvas.GraphicsContext.strokePolygon(GraphicsContext.java:1591)
at Experiment.MakeMap.drawShape(MakeMap.java:199)
at Experiment.MakeMap.start(MakeMap.java:129)
at com.sun.javafx.application.LauncherImpl$5.run(LauncherImpl.java:319)
at com.sun.javafx.application.PlatformImpl$5.run(PlatformImpl.java:216)
at com.sun.javafx.application.PlatformImpl$4$1.run(PlatformImpl.java:179)
at com.sun.javafx.application.PlatformImpl$4$1.run(PlatformImpl.java:176)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl$4.run(PlatformImpl.java:176)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:76)
at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
at com.sun.glass.ui.gtk.GtkApplication$3$1.run(GtkApplication.java:89)
... 1 more
https://drive.google.com/file/d/0B9nTZs5-E8czSEl4aXpwYjZhdUE/edit?usp=sharing world.shp
https://drive.google.com/file/d/0B9nTZs5-E8czT2RITnY5ZjFmTnM/edit?usp=sharing shapefilereader.jar
I am trying to color different region of a polar chart with different colors. e.g coloring the region between the angle 20 and 60 and between the radii 2 and 4.
How can I do this? I was thinking of using a shape annotation and from there drawing an arc, but it seems there is no shape annotation for polar plots.
Any ideas?
Thank you
import java.awt.Color;
import java.awt.Dimension;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.NumberTick;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.PolarPlot;
import org.jfree.chart.renderer.DefaultPolarItemRenderer;
import org.jfree.chart.renderer.PolarItemRenderer;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.ui.TextAnchor;
public class test2 extends JFrame {
private static final String title = "Archimedes' Spiral";
public test2(String title) {
super(title);
JFreeChart chart = createChart(createDataset());
ChartPanel panel = new ChartPanel(chart);
panel.setPreferredSize(new Dimension(500, 500));
panel.setMouseZoomable(false);
this.add(panel);
}
private static XYDataset createDataset() {
XYSeriesCollection result = new XYSeriesCollection();
XYSeries series = new XYSeries(title);
XYSeries ser = new XYSeries("test");
for (int t = 0; t <= 1 * 360; t++) {
series.add(90 - t, t);
}
for (int t = 0; t <= 1 * 120; t++) {
ser.add(90 - t, 40);
ser.add(90 - t, 120);
}
result.addSeries(series);
result.addSeries(ser);
return result;
}
private static JFreeChart createChart(XYDataset dataset) {
ValueAxis radiusAxis = new NumberAxis();
radiusAxis.setTickLabelsVisible(false);
PolarItemRenderer renderer = new DefaultPolarItemRenderer();
PolarPlot plot = new PolarPlot(dataset, radiusAxis, renderer) {
#Override
protected List refreshAngleTicks() {
List<NumberTick> ticks = new ArrayList<NumberTick>();
int delta = (int) this.getAngleTickUnit().getSize();
for (int t = 0; t < 360; t += delta) {
int tp = (360 + 90 - t) % 360;
NumberTick tick = new NumberTick(
Double.valueOf(t), String.valueOf(tp),
TextAnchor.CENTER, TextAnchor.CENTER, 0.0);
ticks.add(tick);
}
return ticks;
}
};
plot.setBackgroundPaint(new Color(0x00f0f0f0));
plot.setRadiusGridlinePaint(Color.gray);
plot.addCornerTextItem("r(θ) = θ; 0 < θ < 6π");
DefaultPolarItemRenderer ren = new DefaultPolarItemRenderer();
ren.setSeriesFilled(0, true);
ren.setSeriesFilled(1, true);
plot.setRenderer(ren);
JFreeChart chart = new JFreeChart(
title, JFreeChart.DEFAULT_TITLE_FONT, plot, true);
chart.setBackgroundPaint(Color.white);
return chart;
}
public static void main(String[] args) {
test2 demo = new test2(title);
demo.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
demo.pack();
demo.setLocationRelativeTo(null);
demo.setVisible(true);
}
}
The DefaultPolarItemRenderer typically used in a PolarPlot has the method setSeriesFilled(), which controls whether a series is filled. The renderer specifies the AlphaComposite.SRC_OVER mode with a value of 50%, so overlapping fills look especially nice.
Addendum: To create the chart seen below, start with this example and reduce the data set's domain from 6π to 2π in createDataset():
for (int t = 0; t <= 1 * 360; t++) { ...
Then make the series filled in createChart():
...
DefaultPolarItemRenderer renderer = new DefaultPolarItemRenderer();
renderer.setSeriesFilled(0, true);
...
I am trying to create a filled series over each region of a polar plot. But the colors are not filled out right. Here is an image of what I get: http://i1122.photobucket.com/albums/l539/jpo2/polar-1.gif
Here is the code I have to loop through a given section is as follows:
if (i < 8) {
for(int r = 0; r< 20; r+=(NumberAxis) plot.getAxis()).getTickUnit().getSize()){
for(int theta = 0; theta <= 180; theta+=30){
XYSeries series = new XYSeries(i + "π/8 " + "< θ < 2π+" + i + "π/8");
for (int e = theta; e < theta+30; e++) {
series.add(90-e-i*45, r);
series.add(90-e-i*45, r- ((NumberAxis) plot.getAxis()).getTickUnit().getSize());
}
result.addSeries(series);
setFilled(result);
i++;
}
}
}
private void setFilled(XYDataset dataset) {
for (int i = 0; i < dataset.getSeriesCount(); i++) {
renderers.setSeriesFilled(i, true);
}
}
This is a modification of #trashgod's draw method at JFreechart Loop through polar chart sectors
Please help.
Full code:
import java.awt.Color;
import java.awt.Dimension;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.NumberTick;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.event.ChartProgressEvent;
import org.jfree.chart.event.ChartProgressListener;
import org.jfree.chart.plot.PolarPlot;
import org.jfree.chart.renderer.DefaultPolarItemRenderer;
import org.jfree.chart.renderer.PolarItemRenderer;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.ui.TextAnchor;
public class tests extends JFrame implements ChartProgressListener {
private static final String title = "Archimedes' Spirals";
private XYSeriesCollection result = new XYSeriesCollection();
private DefaultPolarItemRenderer renderers = new DefaultPolarItemRenderer();
private int i;
public tests(String title) {
super(title);
JFreeChart chart = createChart(result);
ChartPanel panel = new ChartPanel(chart);
panel.setPreferredSize(new Dimension(500, 500));
panel.setMouseZoomable(false);
this.add(panel);
}
private JFreeChart createChart(XYDataset dataset) {
ValueAxis radiusAxis = new NumberAxis();
radiusAxis.setTickLabelsVisible(false);
PolarItemRenderer renderer = new DefaultPolarItemRenderer();
PolarPlot plot = new PolarPlot(dataset, radiusAxis, renderer) {
#Override
protected List refreshAngleTicks() {
List<NumberTick> ticks = new ArrayList<NumberTick>();
int delta = (int) this.getAngleTickUnit().getSize();
for (int t = 0; t < 360; t += delta) {
int tp = (360 + 90 - t) % 360;
NumberTick tick = new NumberTick(
Double.valueOf(t), String.valueOf(tp),
TextAnchor.CENTER, TextAnchor.CENTER, 0.0);
ticks.add(tick);
}
return ticks;
}
};
plot.setBackgroundPaint(new Color(0x00f0f0f0));
plot.setRadiusGridlinePaint(Color.gray);
plot.addCornerTextItem("r(θ) = θ; 0 < θ < 2π; +iπ/8");
setFilled(dataset);
plot.setRenderer(renderers);
JFreeChart chart = new JFreeChart(
title, JFreeChart.DEFAULT_TITLE_FONT, plot, true);
chart.setBackgroundPaint(Color.white);
chart.addProgressListener(this);
return chart;
}
public static void main(String[] args) {
tests demo = new tests(title);
demo.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
demo.pack();
demo.setLocationRelativeTo(null);
demo.setVisible(true);
}
#Override
public void chartProgress(ChartProgressEvent e) {
if (e.getType() == ChartProgressEvent.DRAWING_FINISHED) {
System.out.println(e);
JFreeChart chart = e.getChart();
draw();
}
}
public void draw() {
if (i < 4) {
for (int g = 0; g < 30; g += 5) {
for (int h = 0; h < 180; h += 45) {
XYSeries series = new XYSeries(i + "π/8 " + "< θ < 2π+" + i + "π/8");
for (int t = h; t <= h + 45; t++) {
series.add(90 - t, g);
series.add(90 - t, g + 5);
}
result.addSeries(series);
setFilled(result);
i++;
}
}
}
}
private void setFilled(XYDataset dataset) {
for (int i = 0; i < dataset.getSeriesCount(); i++) {
renderers.setSeriesFilled(i, true);
}
}
}
Here's a simplified version the uses PolarPlot directly, without any transformation. It might be easier to experiment with.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.JFrame;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.PolarPlot;
import org.jfree.chart.renderer.DefaultPolarItemRenderer;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
/** #see http://stackoverflow.com/questions/6669734 */
public class PolarArcs {
private static final String title = "PolarArcs";
private static final double PI2 = 90d; // π/2 radians = 90°
private void display() {
JFrame f = new JFrame(title);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ChartPanel panel = new ChartPanel(createChart(createDataset()));
panel.setPreferredSize(new Dimension(400, 400));
f.add(panel);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private JFreeChart createChart(XYDataset dataset) {
JFreeChart chart = ChartFactory.createPolarChart(
title, dataset, true, false, false);
PolarPlot plot = (PolarPlot) chart.getPlot();
plot.setBackgroundPaint(Color.white);
plot.setAngleGridlinesVisible(false);
plot.setRadiusGridlinesVisible(false);
DefaultPolarItemRenderer r = (DefaultPolarItemRenderer) plot.getRenderer();
for (int i = 0; i < dataset.getSeriesCount(); i++ ) {
r.setSeriesFilled(i, true);
}
NumberAxis rangeAxis = (NumberAxis) plot.getAxis();
rangeAxis.setTickLabelsVisible(false);
return chart;
}
private XYDataset createDataset() {
XYSeriesCollection result = new XYSeriesCollection();
for (int r = 8; r > 0; r--) {
XYSeries series = new XYSeries(title + String.valueOf(r));
for (int t = (int) -PI2; t <= PI2; t++) {
series.add(t, r);
}
result.addSeries(series);
}
return result;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new PolarArcs().display();
}
});
}
}