001/* 002Copyright 2006 Jerry Huxtable 003 004Licensed under the Apache License, Version 2.0 (the "License"); 005you may not use this file except in compliance with the License. 006You may obtain a copy of the License at 007 008 http://www.apache.org/licenses/LICENSE-2.0 009 010Unless required by applicable law or agreed to in writing, software 011distributed under the License is distributed on an "AS IS" BASIS, 012WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013See the License for the specific language governing permissions and 014limitations under the License. 015*/ 016 017package com.jhlabs.image; 018 019import java.awt.*; 020import java.awt.geom.*; 021import java.awt.image.*; 022 023/** 024 * A filter which wraps an image around a circular arc. 025 */ 026public class CircleFilter extends TransformFilter { 027 028 private float radius = 10; 029 private float height = 20; 030 private float angle = 0; 031 private float spreadAngle = (float)Math.PI; 032 private float centreX = 0.5f; 033 private float centreY = 0.5f; 034 035 private float icentreX; 036 private float icentreY; 037 private float iWidth; 038 private float iHeight; 039 040 /** 041 * Construct a CircleFilter. 042 */ 043 public CircleFilter() { 044 setEdgeAction( ZERO ); 045 } 046 047 /** 048 * Set the height of the arc. 049 * @param height the height 050 * @see #getHeight 051 */ 052 public void setHeight(float height) { 053 this.height = height; 054 } 055 056 /** 057 * Get the height of the arc. 058 * @return the height 059 * @see #setHeight 060 */ 061 public float getHeight() { 062 return height; 063 } 064 065 /** 066 * Set the angle of the arc. 067 * @param angle the angle of the arc. 068 * @angle 069 * @see #getAngle 070 */ 071 public void setAngle(float angle) { 072 this.angle = angle; 073 } 074 075 /** 076 * Returns the angle of the arc. 077 * @return the angle of the arc. 078 * @see #setAngle 079 */ 080 public float getAngle() { 081 return angle; 082 } 083 084 /** 085 * Set the spread angle of the arc. 086 * @param spreadAngle the angle 087 * @angle 088 * @see #getSpreadAngle 089 */ 090 public void setSpreadAngle(float spreadAngle) { 091 this.spreadAngle = spreadAngle; 092 } 093 094 /** 095 * Get the spread angle of the arc. 096 * @return the angle 097 * @angle 098 * @see #setSpreadAngle 099 */ 100 public float getSpreadAngle() { 101 return spreadAngle; 102 } 103 104 /** 105 * Set the radius of the effect. 106 * @param radius the radius 107 * @min-value 0 108 * @see #getRadius 109 */ 110 public void setRadius(float radius) { 111 this.radius = radius; 112 } 113 114 /** 115 * Get the radius of the effect. 116 * @return the radius 117 * @see #setRadius 118 */ 119 public float getRadius() { 120 return radius; 121 } 122 123 /** 124 * Set the centre of the effect in the Y direction as a proportion of the image size. 125 * @param centreX the center 126 * @see #getCentreX 127 */ 128 public void setCentreX( float centreX ) { 129 this.centreX = centreX; 130 } 131 132 /** 133 * Get the centre of the effect in the X direction as a proportion of the image size. 134 * @return the center 135 * @see #setCentreX 136 */ 137 public float getCentreX() { 138 return centreX; 139 } 140 141 /** 142 * Set the centre of the effect in the Y direction as a proportion of the image size. 143 * @param centreY the center 144 * @see #getCentreY 145 */ 146 public void setCentreY( float centreY ) { 147 this.centreY = centreY; 148 } 149 150 /** 151 * Get the centre of the effect in the Y direction as a proportion of the image size. 152 * @return the center 153 * @see #setCentreY 154 */ 155 public float getCentreY() { 156 return centreY; 157 } 158 159 /** 160 * Set the centre of the effect as a proportion of the image size. 161 * @param centre the center 162 * @see #getCentre 163 */ 164 public void setCentre( Point2D centre ) { 165 this.centreX = (float)centre.getX(); 166 this.centreY = (float)centre.getY(); 167 } 168 169 /** 170 * Get the centre of the effect as a proportion of the image size. 171 * @return the center 172 * @see #setCentre 173 */ 174 public Point2D getCentre() { 175 return new Point2D.Float( centreX, centreY ); 176 } 177 178 public BufferedImage filter( BufferedImage src, BufferedImage dst ) { 179 iWidth = src.getWidth(); 180 iHeight = src.getHeight(); 181 icentreX = iWidth * centreX; 182 icentreY = iHeight * centreY; 183 iWidth--; 184 return super.filter( src, dst ); 185 } 186 187 protected void transformInverse(int x, int y, float[] out) { 188 float dx = x-icentreX; 189 float dy = y-icentreY; 190 float theta = (float)Math.atan2( -dy, -dx ) + angle; 191 float r = (float)Math.sqrt( dx*dx + dy*dy ); 192 193 theta = ImageMath.mod( theta, 2*(float)Math.PI ); 194 195 out[0] = iWidth * theta/(spreadAngle+0.00001f); 196 out[1] = iHeight * (1-(r-radius)/(height+0.00001f)); 197 } 198 199 public String toString() { 200 return "Distort/Circle..."; 201 } 202 203}