1 /* $RCSfile$
2  * $Author: hansonr $
3  * $Date: 2015-04-30 08:17:17 -0500 (Thu, 30 Apr 2015) $
4  * $Revision: 20465 $
5  *
6  * Copyright (C) 2003-2005  Miguel, Jmol Development, www.jmol.org
7  *
8  * Contact: jmol-developers@lists.sf.net
9  *
10  *  This library is free software; you can redistribute it and/or
11  *  modify it under the terms of the GNU Lesser General Public
12  *  License as published by the Free Software Foundation; either
13  *  version 2.1 of the License, or (at your option) any later version.
14  *
15  *  This library is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  *  Lesser General Public License for more details.
19  *
20  *  You should have received a copy of the GNU Lesser General Public
21  *  License along with this library; if not, write to the Free Software
22  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
23  */
24 package org.jmol.g3d;
25 
26 import org.jmol.api.JmolRendererInterface;
27 import org.jmol.util.GData;
28 
29 /**
30  * <p>
31  * Implements flat circle drawing/filling routines.
32  * </p>
33  *
34  * @author Miguel, miguel@jmol.org
35  */
36 public final class CircleRenderer implements G3DRenderer {
37 
38   private Graphics3D g3d;
39 
CircleRenderer()40   public CircleRenderer() {
41     // for reflection
42   }
43 
44   @Override
set(JmolRendererInterface g3d, GData gdata)45   public G3DRenderer set(JmolRendererInterface g3d, GData gdata) {
46     try {
47       this.g3d = (Graphics3D) g3d;
48     } catch (Exception e) {
49       // must be export; not a problem
50     }
51     return this;
52   }
53 
plotCircleCenteredClipped(int xCenter, int yCenter, int zCenter, int diameter)54   void plotCircleCenteredClipped(int xCenter, int yCenter, int zCenter,
55                                  int diameter) {
56     Graphics3D g = g3d;
57     int c = g.argbCurrent;
58     int width = g.width;
59     int[] zbuf = g.zbuf;
60     Pixelator p = g.pixel;
61     // halo only -- simple window clip
62     int r = diameter / 2;
63     int sizeCorrection = 1 - (diameter & 1);
64     int x = r;
65     int y = 0;
66     int xChange = 1 - 2 * r;
67     int yChange = 1;
68     int radiusError = 0;
69     while (x >= y) {
70       g.plotPixelClippedArgb(c, xCenter + x - sizeCorrection, yCenter + y
71           - sizeCorrection, zCenter, width, zbuf, p);
72       g.plotPixelClippedArgb(c, xCenter + x - sizeCorrection, yCenter - y,
73           zCenter, width, zbuf, p);
74       g.plotPixelClippedArgb(c, xCenter - x, yCenter + y - sizeCorrection,
75           zCenter, width, zbuf, p);
76       g.plotPixelClippedArgb(c, xCenter - x, yCenter - y, zCenter, width, zbuf,
77           p);
78 
79       g.plotPixelClippedArgb(c, xCenter + y - sizeCorrection, yCenter + x
80           - sizeCorrection, zCenter, width, zbuf, p);
81       g.plotPixelClippedArgb(c, xCenter + y - sizeCorrection, yCenter - x,
82           zCenter, width, zbuf, p);
83       g.plotPixelClippedArgb(c, xCenter - y, yCenter + x - sizeCorrection,
84           zCenter, width, zbuf, p);
85       g.plotPixelClippedArgb(c, xCenter - y, yCenter - x, zCenter, width, zbuf,
86           p);
87       ++y;
88       radiusError += yChange;
89       yChange += 2;
90       if (2 * radiusError + xChange > 0) {
91         --x;
92         radiusError += xChange;
93         xChange += 2;
94       }
95     }
96   }
97 
plotCircleCenteredUnclipped(int xCenter, int yCenter, int zCenter, int diameter)98   void plotCircleCenteredUnclipped(int xCenter, int yCenter, int zCenter,
99                                    int diameter) {
100     int r = diameter / 2;
101     int sizeCorrection = 1 - (diameter & 1);
102     int x = r;
103     int y = 0;
104     int xChange = 1 - 2 * r;
105     int yChange = 1;
106     int radiusError = 0;
107     Graphics3D g = g3d;
108     Pixelator p = g.pixel;
109     int width = g.width;
110     int[] zbuf = g.zbuf;
111     int c = g.argbCurrent;
112 
113     while (x >= y) {
114       g.plotPixelUnclipped(c, xCenter + x - sizeCorrection, yCenter + y
115           - sizeCorrection, zCenter, width, zbuf, p);
116       g.plotPixelUnclipped(c, xCenter + x - sizeCorrection, yCenter - y,
117           zCenter, width, zbuf, p);
118       g.plotPixelUnclipped(c, xCenter - x, yCenter + y - sizeCorrection,
119           zCenter, width, zbuf, p);
120       g.plotPixelUnclipped(c, xCenter - x, yCenter - y, zCenter, width, zbuf, p);
121 
122       g.plotPixelUnclipped(c, xCenter + y - sizeCorrection, yCenter + x
123           - sizeCorrection, zCenter, width, zbuf, p);
124       g.plotPixelUnclipped(c, xCenter + y - sizeCorrection, yCenter - x,
125           zCenter, width, zbuf, p);
126       g.plotPixelUnclipped(c, xCenter - y, yCenter + x - sizeCorrection,
127           zCenter, width, zbuf, p);
128       g.plotPixelUnclipped(c, xCenter - y, yCenter - x, zCenter, width, zbuf, p);
129       ++y;
130       radiusError += yChange;
131       yChange += 2;
132       if (2 * radiusError + xChange > 0) {
133         --x;
134         radiusError += xChange;
135         xChange += 2;
136       }
137     }
138   }
139 
plotFilledCircleCenteredClipped(int xCenter, int yCenter, int zCenter, int diameter)140   void plotFilledCircleCenteredClipped(int xCenter, int yCenter, int zCenter,
141                                        int diameter) {
142     // for halo only
143     int r = diameter / 2;
144     int sizeCorrection = 1 - (diameter & 1);
145     int x = r;
146     int y = 0;
147     int xChange = 1 - 2 * r;
148     int yChange = 1;
149     int radiusError = 0;
150     Graphics3D g = g3d;
151     int c = g.argbCurrent;
152     int width = g.width;
153     int height = g.height;
154     int[] zbuf = g.zbuf;
155     Pixelator p = g.pixel;
156 
157     while (x >= y) {
158       plotPixelsClipped(c, 2 * x + 1 - sizeCorrection, xCenter - x, yCenter
159           + y - sizeCorrection, zCenter, width, height, zbuf, p);
160       plotPixelsClipped(c, 2 * x + 1 - sizeCorrection, xCenter - x, yCenter
161           - y, zCenter, width, height, zbuf, p);
162       plotPixelsClipped(c, 2 * y + 1 - sizeCorrection, xCenter - y, yCenter
163           + x - sizeCorrection, zCenter, width, height, zbuf, p);
164       plotPixelsClipped(c, 2 * y + 1 - sizeCorrection, xCenter - y, yCenter
165           - x, zCenter, width, height, zbuf, p);
166       ++y;
167       radiusError += yChange;
168       yChange += 2;
169       if (2 * radiusError + xChange > 0) {
170         --x;
171         radiusError += xChange;
172         xChange += 2;
173       }
174     }
175   }
176 
plotPixelsClipped(int argb, int count, int x, int y, int z, int width, int height, int[] zbuf, Pixelator p)177   private void plotPixelsClipped(int argb, int count, int x, int y, int z, int width,
178                          int height, int[] zbuf, Pixelator p) {
179     // for circle only; i.e. halo
180     // simple Z/window clip
181     if (y < 0 || y >= height || x >= width)
182       return;
183     if (x < 0) {
184       count += x; // x is negative, so this is subtracting -x
185       x = 0;
186     }
187     if (count + x > width)
188       count = width - x;
189     if (count <= 0)
190       return;
191     int offsetPbuf = y * width + x;
192     int offsetMax = offsetPbuf + count;
193     while (offsetPbuf < offsetMax) {
194       if (z < zbuf[offsetPbuf])
195         p.addPixel(offsetPbuf, z, argb);
196       offsetPbuf++;// += step;
197     }
198   }
199 
plotFilledCircleCenteredUnclipped(int xCenter, int yCenter, int zCenter, int diameter)200   void plotFilledCircleCenteredUnclipped(int xCenter, int yCenter, int zCenter,
201                                          int diameter) {
202     // for halo only
203     int r = diameter / 2;
204     int x = r;
205     int y = 0;
206     int xChange = 1 - 2 * r;
207     int yChange = 1;
208     int radiusError = 0;
209     Graphics3D g = g3d;
210     int c = g.argbCurrent;
211     int width = g.width;
212     int[] zbuf = g.zbuf;
213     Pixelator p = g.pixel;
214     while (x >= y) {
215       g.plotPixelsUnclippedCount(c, 2 * x + 1, xCenter - x, yCenter + y,
216           zCenter, width, zbuf, p);
217       g.plotPixelsUnclippedCount(c, 2 * x + 1, xCenter - x, yCenter - y,
218           zCenter, width, zbuf, p);
219       g.plotPixelsUnclippedCount(c, 2 * y + 1, xCenter - y, yCenter + x,
220           zCenter, width, zbuf, p);
221       g.plotPixelsUnclippedCount(c, 2 * y + 1, xCenter - y, yCenter - x,
222           zCenter, width, zbuf, p);
223       ++y;
224       radiusError += yChange;
225       yChange += 2;
226       if (2 * radiusError + xChange > 0) {
227         --x;
228         radiusError += xChange;
229         xChange += 2;
230       }
231     }
232   }
233 
234 }
235