PDA

View Full Version : Looking for a 2D Polygon Bevel Algorithm


khilen
06-28-2005, 11:28 PM
I am looking for a graphics algorithm to give two-dimensional polygons
a 3D beveled edge look. The polygon should look like as though it is
lit from the top-left. This is trivial for rectangular figures, but
obviously much more complex for general polygons. The algorithm needs
to support any type of polygon, including those with splines or other
curved edges, as well as convex figures. Making matters even more
complicated, it must also handle texture-filled polygons.
A Java class that provides this functionality would be perfect. Short
of that, an implementation in any language, or even a description of an
algorithm, would be helpful.


I created a java applet to illustrate the problem I am trying to solve
- see the source below. This applet with source is also available at


http://www.keithhilen.com/Java/bevel/


Keith Hilen

keith@hilensystems.com


------------------------------------------------------------
Polygons.java:


import java.applet.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.geom.*;

public class Polygons extends Applet
{
Image image;

int polyWidth = 100;
int polyHeight = polyWidth;

int polyOfsX1 = 100;
int polyOfsY1 = 100;

int polyOfsX2 = 250;
int polyOfsY2 = 100;

int polyOfsX3 = 100;
int polyOfsY3 = 240;

int polyOfsX4 = 250;
int polyOfsY4 = 240;

Polygon octagon;
Ellipse2D.Double ellipse;
GeneralPath ornament;

BufferedImage imageBuf1, imageBuf2, imageBuf3, imageBuf4;

public void init()
{
image = loadImage("background.jpg");
createPolygons();
createImageBufs();
}

private Image loadImage(String name)
{
MediaTracker tracker = new MediaTracker(this);
Image image = getImage(getDocumentBase(), name);
tracker.addImage(image, 0);
for ( ; ; )
{
try { tracker.waitForAll(); } catch (InterruptedException e) { }
if (tracker.checkAll())
break;
}
return image;
}

public void createPolygons()
{
double sqrt2 = Math.sqrt(2);
int m1 = (int) (polyWidth / (2 + sqrt2));
int m2 = (int) (polyWidth * sqrt2 / (2 + sqrt2));

octagon = new Polygon();
octagon.addPoint(-m2/2, -(m1 + m2/2));
octagon.addPoint(+m2/2, -(m1 + m2/2));
octagon.addPoint(+(m1 + m2/2), -(m2/2));
octagon.addPoint(+(m1 + m2/2), +(m2/2));
octagon.addPoint(+m2/2, +(m1 + m2/2));
octagon.addPoint(-m2/2, +(m1 + m2/2));
octagon.addPoint(-(m1 + m2/2), +(m2/2));
octagon.addPoint(-(m1 + m2/2), -(m2/2));

ellipse = new Ellipse2D.Double(-polyWidth/2, -polyWidth/2, polyWidth, polyWidth*3/4);

ornament = new GeneralPath();

int l = polyWidth/2;
int m = polyWidth/16;
int s = polyWidth/32;

ornament.moveTo(+0+0, -l+0);

ornament.quadTo(+0+s, -l+0, +0+s, -l+s);
ornament.quadTo(+m+0, -m+0, +l-s, +0-s);
ornament.quadTo(+l+0, +0-s, +l+0, +0+0);

ornament.quadTo(+l+0, +0+s, +l-s, +0+s);
ornament.quadTo(+m+0, +m+0, +0+s, +l-s);
ornament.quadTo(+0+s, +l-0, +0+0, +l+0);

ornament.quadTo(+0-s, +l+0, +0-s, +l-s);
ornament.quadTo(-m+0, +m+0, -l+s, +0+s);
ornament.quadTo(-l+0, +0+s, -l+0, +0+0);

ornament.quadTo(-l+0, +0-s, -l+s, +0-s);
ornament.quadTo(-m+0, -m+0, +0-s, -l+s);
ornament.quadTo(+0-s, -l+0, -0+0, -l+0);

}

public void createImageBufs()
{
Graphics2D g2d;
Composite saveAlpha;

// Figure 1
// Create image buf and get context
imageBuf1 = new BufferedImage(polyWidth, polyHeight, BufferedImage.TYPE_INT_ARGB_PRE);
g2d = (Graphics2D) imageBuf1.getGraphics();
// Fill with transparent color
saveAlpha = g2d.getComposite();
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0f));
g2d.fillRect(0, 0, polyWidth, polyHeight);
g2d.setComposite(saveAlpha);
// Draw figure
g2d.translate(polyWidth/2, polyHeight/2);
g2d.setClip(octagon);
g2d.setColor(Color.blue);
g2d.fillRect(-polyWidth/2, -polyHeight/2, polyWidth, polyHeight);

// Figure 2
// Create image buf and get context
imageBuf2 = new BufferedImage(polyWidth, polyHeight, BufferedImage.TYPE_INT_ARGB_PRE);
g2d = (Graphics2D) imageBuf2.getGraphics();
// Fill with transparent color
saveAlpha = g2d.getComposite();
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0f));
g2d.fillRect(0, 0, polyWidth, polyHeight);
g2d.setComposite(saveAlpha);
// Draw figure
g2d.translate(polyWidth/2, polyHeight/2);
g2d.setClip(octagon);
g2d.drawImage(image, -polyWidth/2, -polyWidth/2, null);

// Figure 3
// Create image buf and get context
imageBuf3 = new BufferedImage(polyWidth, polyHeight, BufferedImage.TYPE_INT_ARGB_PRE);
g2d = (Graphics2D) imageBuf3.getGraphics();
// Fill with transparent color
saveAlpha = g2d.getComposite();
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0f));
g2d.fillRect(0, 0, polyWidth, polyHeight);
g2d.setComposite(saveAlpha);
// Draw figure
g2d.translate(polyWidth/2, polyHeight/2);
g2d.setClip(ellipse);
g2d.drawImage(image, -polyWidth/2, -polyWidth*5/8, null);

// Figure 4
// Create image buf and get context
imageBuf4 = new BufferedImage(polyWidth, polyHeight, BufferedImage.TYPE_INT_ARGB_PRE);
g2d = (Graphics2D) imageBuf4.getGraphics();
// Fill with transparent color
saveAlpha = g2d.getComposite();
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0f));
g2d.fillRect(0, 0, polyWidth, polyHeight);
g2d.setComposite(saveAlpha);
// Draw figure
g2d.translate(polyWidth/2, polyHeight/2);
g2d.setClip(ornament);
g2d.drawImage(image, -polyWidth/2, -polyWidth/2, null);

}

public void paint(Graphics g)
{
g.drawImage(imageBuf1, polyOfsX1 - polyWidth/2, polyOfsY1 - polyHeight/2, null);
g.drawImage(imageBuf2, polyOfsX2 - polyWidth/2, polyOfsY2 - polyHeight/2, null);
g.drawImage(imageBuf3, polyOfsX3 - polyWidth/2, polyOfsY3 - polyHeight/2, null);
g.drawImage(imageBuf4, polyOfsX4 - polyWidth/2, polyOfsY4 - polyHeight/2, null);
}

}

Polygons.html:


<applet
code=Polygons.class
name=Polygons
width=360
height=300>
</applet>

CGTalk Moderation
06-28-2005, 11:28 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.