How to create an Elliptical Gradient (e.g, implement PaintContext).

Hi,

I found an implementation of a circle gradient that works well.

Search this page for RoundGradientPaint and RoundGradientContext:

http://www.oreilly.com/catalog/java2d/chapter/ch04.html

My question is this: How do I modify this code to draw an elliptical gradient instead only a circle gradient? I would really appreciate any help.

Thanks!

[380 byte] By [jvaudrya] at [2007-10-3 7:53:22]
# 1
HelloDoes anybody know more books that explain more of the Paint Interface, I have troubles with that too!bye!
RaulHuertasa at 2007-7-15 2:55:37 > top of Java-index,Security,Cryptography...
# 2

import java.awt.*;

import java.awt.geom.*;

import java.awt.image.*;

import java.util.*;

import javax.swing.*;

import javax.swing.event.*;

public class EllipticalGradient extends JPanel {

Point2D.Double p = new Point2D.Double(175, 75);

protected void paintComponent(Graphics g) {

super.paintComponent(g);

Graphics2D g2 = (Graphics2D)g;

g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,

RenderingHints.VALUE_ANTIALIAS_ON);

Rectangle r = getBounds();

double cx = r.getCenterX();

double cy = r.getCenterY();

OvalGradientPaint ogp =

new OvalGradientPaint(cx, cy, Color.magenta, p, Color.blue);

g2.setPaint(ogp);

g2.fill(r);

}

public static void main(String[] args) {

EllipticalGradient eg = new EllipticalGradient();

JFrame f = new JFrame();

f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

f.add(eg);

f.add(eg.getControls(), "Last");

f.setSize(400,400);

f.setLocationRelativeTo(null);

f.setVisible(true);

}

private JPanel getControls() {

final JSlider xSlider = new JSlider(10, 200, (int)p.x);

final JSlider ySlider = new JSlider(10, 200, (int)p.y);

ChangeListener l = new ChangeListener() {

public void stateChanged(ChangeEvent e) {

JSlider slider = (JSlider)e.getSource();

double value = slider.getValue();

if(slider == xSlider)

p.x = value;

else if(slider == ySlider)

p.y = value;

repaint();

}

};

xSlider.addChangeListener(l);

ySlider.addChangeListener(l);

JPanel panel = new JPanel(new GridBagLayout());

GridBagConstraints gbc = new GridBagConstraints();

gbc.insets = new Insets(2,2,2,2);

gbc.fill = gbc.HORIZONTAL;

addComponents(new JLabel("p.x"), xSlider, panel, gbc);

addComponents(new JLabel("p.y"), ySlider, panel, gbc);

return panel;

}

private void addComponents(Component c1, Component c2, Container c,

GridBagConstraints gbc) {

gbc.weightx = 0;

gbc.gridwidth = gbc.RELATIVE;

c.add(c1, gbc);

gbc.weightx = 1.0;

gbc.gridwidth = gbc.REMAINDER;

c.add(c2, gbc);

}

}

class OvalGradientPaint implements Paint {

protected Point2D mPoint;

protected Point2D mRadius;

protected Color mPointColor, mBackgroundColor;

public OvalGradientPaint(double x, double y, Color pointColor,

Point2D radius, Color backgroundColor) {

if(radius.distance(0,0)<=0)

throw new IllegalArgumentException("Radius must be greater than 0.");

mPoint = new Point2D.Double(x,y);

mPointColor = pointColor;

mRadius = radius;

mBackgroundColor = backgroundColor;

}

public PaintContext createContext(ColorModel cm,

Rectangle deviceBounds,

Rectangle2D userBounds,

AffineTransform xform,

RenderingHints hints) {

Point2D transformedPoint = xform.transform(mPoint,null);

Point2D transformedRadius = xform.deltaTransform(mRadius,null);

return new OvalGradientContext(transformedPoint, mPointColor,

transformedRadius, mBackgroundColor);

}

public int getTransparency() {

int a1 = mPointColor.getAlpha();

int a2 = mBackgroundColor.getAlpha();

return (((a1 & a2) == 0xff) ? OPAQUE : TRANSLUCENT);

}

}

class OvalGradientContext implements PaintContext {

protected Point2D mPoint;

protected Point2D mRadius;

protected Color mC1, mC2;

Ellipse2D.Double ellipse;

Line2D.Double line;

Map<Double, Double> lookup;

double R;

public OvalGradientContext(Point2D p, Color c1, Point2D r, Color c2) {

mPoint = p;

mC1 = c1;

mRadius = r;

mC2 = c2;

double x = p.getX() - mRadius.getX();

double y = p.getY() - mRadius.getY();

double w = 2*mRadius.getX();

double h = 2*mRadius.getY();

ellipse = new Ellipse2D.Double(x,y,w,h);

line = new Line2D.Double();

R = Point2D.distance(0, 0, r.getX(), r.getY());

initLookup();

}

public void dispose() { }

public ColorModel getColorModel() {

return ColorModel.getRGBdefault();

}

public Raster getRaster(int x, int y, int w, int h) {

WritableRaster raster = getColorModel().createCompatibleWritableRaster(w,h);

int[] data = new int[w*h*4];

for(int j = 0; j < h; j++) {

for(int i = 0; i < w; i++) {

double distance = mPoint.distance(x+i,y+j);

double dy = y+j - mPoint.getY();

double dx = x+i - mPoint.getX();

double theta = Math.atan2(dy, dx);

double xp = mPoint.getX() + R * Math.cos(theta);

double yp = mPoint.getY() + R * Math.sin(theta);

line.setLine(mPoint.getX(), mPoint.getY(), xp, yp);

double roundDegrees = Math.round(Math.toDegrees(theta));

double radius = lookup.get(Double.valueOf(roundDegrees));

double ratio = distance / radius;

if(ratio > 1.0)

ratio = 1.0;

int base = (j * w + i) * 4;

data[base + 0] = (int)(mC1.getRed() +

ratio * (mC2.getRed() - mC1.getRed()));

data[base + 1] = (int)(mC1.getGreen() +

ratio * (mC2.getGreen() - mC1.getGreen()));

data[base + 2] = (int)(mC1.getBlue() +

ratio * (mC2.getBlue() - mC1.getBlue()));

data[base + 3] = (int)(mC1.getAlpha() +

ratio * (mC2.getAlpha() - mC1.getAlpha()));

}

}

raster.setPixels(0,0,w,h,data);

return raster;

}

private double getRadius() {

double[] coords = new double[6];

Point2D.Double p = new Point2D.Double();

double minDistance = Double.MAX_VALUE;

double flatness = 0.005;

PathIterator pit = ellipse.getPathIterator(null, flatness);

while(!pit.isDone()) {

int segment = pit.currentSegment(coords);

switch(segment) {

case PathIterator.SEG_CLOSE:

case PathIterator.SEG_MOVETO:

case PathIterator.SEG_LINETO:

break;

default:

System.out.printf("unexpected segment: %d%n", segment);

}

double distance = line.ptSegDist(coords[0], coords[1]);

if(distance < minDistance) {

minDistance = distance;

p.x = coords[0];

p.y = coords[1];

}

pit.next();

}

return mPoint.distance(p);

}

private void initLookup() {

lookup = new HashMap<Double, Double>();

for(int j = -180; j <= 180; j++) {

Double key = Double.valueOf(j);

double theta = Math.toRadians(j);

double xp = mPoint.getX() + R * Math.cos(theta);

double yp = mPoint.getY() + R * Math.sin(theta);

line.setLine(mPoint.getX(), mPoint.getY(), xp, yp);

Double value = Double.valueOf(getRadius());

lookup.put(key, value);

}

double theta = -0.0; // avoids NullPointerException

Double key = Double.valueOf(theta);

double xp = mPoint.getX() + R * Math.cos(theta);

double yp = mPoint.getY() + R * Math.sin(theta);

line.setLine(mPoint.getX(), mPoint.getY(), xp, yp);

Double value = Double.valueOf(getRadius());

lookup.put(key, value);

}

}

crwooda at 2007-7-15 2:55:37 > top of Java-index,Security,Cryptography...
# 3
AWESOME!!!
jvaudrya at 2007-7-15 2:55:37 > top of Java-index,Security,Cryptography...