130 |
130 |
|
131 |
131 |
///////////////////////////////////////////////////////////////////////////////////////////////////
|
132 |
132 |
|
133 |
|
private void drawCurrSide(Canvas canvas, Paint paint, int left, int top, float stroke,
|
|
133 |
private void drawCurrSide(Canvas canvas, Paint paint, int left, int bottom, float stroke,
|
134 |
134 |
float pX, float pY, float cX, float cY, float pAngle)
|
135 |
135 |
{
|
136 |
136 |
pX = (0.5f+pX)*TEXTURE_HEIGHT;
|
... | ... | |
148 |
148 |
|
149 |
149 |
// draw a little more - stroke*(aX,aY) more - so
|
150 |
150 |
// that we draw over the rounded corners (Kilominx!)
|
151 |
|
canvas.drawLine(left+pX,top+pY,left+cX-stroke*aX,top+cY-stroke*aY,paint);
|
|
151 |
canvas.drawLine(left+pX,bottom-pY,left+cX-stroke*aX,bottom-cY+stroke*aY,paint);
|
152 |
152 |
}
|
153 |
153 |
else
|
154 |
154 |
{
|
... | ... | |
159 |
159 |
|
160 |
160 |
float dx = ox-pX;
|
161 |
161 |
float dy = oy-pY;
|
162 |
|
float startA = computeAngle(dy,dx);
|
163 |
|
float sweepA = -2*pAngle;
|
|
162 |
float startA = computeAngle(-dy,dx);
|
|
163 |
float sweepA = 2*pAngle;
|
164 |
164 |
|
165 |
165 |
startA *= 180/PI;
|
166 |
166 |
sweepA *= 180/PI;
|
167 |
167 |
|
168 |
|
canvas.drawArc( left+ox-r, top+oy-r, left+ox+r, top+oy+r, startA, sweepA, false, paint);
|
|
168 |
canvas.drawArc( left+ox-r, bottom-oy-r, left+ox+r, bottom-oy+r, startA, sweepA, false, paint);
|
169 |
169 |
}
|
170 |
170 |
}
|
171 |
171 |
|
172 |
172 |
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
173 |
// quotient in (0,1).
|
|
174 |
// quotient==0 --> ret=curvature; quotient==1 --> ret=0.
|
173 |
175 |
|
174 |
|
private float computeSideAngle(float vX, float vY, float curvature)
|
|
176 |
private float computeQuotientOfCurvature(float quotient, float curvature)
|
175 |
177 |
{
|
176 |
|
float ret = computeAngle(vX,vY)+curvature;
|
|
178 |
if( curvature!=0 )
|
|
179 |
{
|
|
180 |
double sinC = Math.sin(curvature);
|
|
181 |
float arcsin = (float)Math.asin(quotient*sinC);
|
|
182 |
return curvature-arcsin;
|
|
183 |
}
|
|
184 |
return curvature;
|
|
185 |
}
|
|
186 |
|
|
187 |
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
188 |
|
|
189 |
private float computeSideAngle(float vX, float vY, float radius, float curvature)
|
|
190 |
{
|
|
191 |
float quotient = radius/(float)Math.sqrt(vX*vX + vY*vY);
|
|
192 |
float ret = computeAngle(vX,-vY)-computeQuotientOfCurvature(quotient,curvature);
|
177 |
193 |
|
178 |
194 |
if( ret>=2*PI ) ret -= 2*PI;
|
179 |
195 |
if( ret<0 ) ret += 2*PI;
|
... | ... | |
200 |
216 |
|
201 |
217 |
///////////////////////////////////////////////////////////////////////////////////////////////////
|
202 |
218 |
|
203 |
|
private void drawRoundCorner(Canvas canvas, Paint paint,int color, int left, int top, float stroke,
|
204 |
|
float radius, float currX, float currY, float pA, float cA)
|
|
219 |
private void drawRoundCorner(Canvas canvas, Paint paint,int color, int left, int bottom, float stroke,
|
|
220 |
float radius, float cX, float cY, float pA, float cA)
|
205 |
221 |
{
|
206 |
|
currX = (0.5f+currX)*TEXTURE_HEIGHT;
|
207 |
|
currY = (0.5f-currY)*TEXTURE_HEIGHT;
|
|
222 |
cX = (0.5f+cX)*TEXTURE_HEIGHT;
|
|
223 |
cY = (0.5f-cY)*TEXTURE_HEIGHT;
|
208 |
224 |
float R = radius*TEXTURE_HEIGHT + stroke/2;
|
209 |
225 |
|
210 |
|
boolean isConvex = (!(pA<cA && cA<pA+PI) && !(pA<cA+2*PI && cA+2*PI<pA+PI));
|
|
226 |
boolean isConvex = ((pA<cA && cA<pA+PI) || (pA<cA+2*PI && cA+2*PI<pA+PI));
|
211 |
227 |
float startA, stopA, centerA, alpha, D;
|
212 |
228 |
|
213 |
229 |
if( isConvex )
|
214 |
230 |
{
|
215 |
|
startA = cA + PI;
|
216 |
|
stopA = pA + PI;
|
|
231 |
startA = cA;
|
|
232 |
stopA = pA;
|
217 |
233 |
if( startA>2*PI ) startA -= 2*PI;
|
218 |
234 |
if( stopA >2*PI ) stopA -= 2*PI;
|
219 |
235 |
centerA= angleMidpoint(pA,cA) - PI/2;
|
... | ... | |
225 |
241 |
}
|
226 |
242 |
else
|
227 |
243 |
{
|
228 |
|
startA = pA;
|
229 |
|
stopA = cA;
|
|
244 |
startA = pA + PI;
|
|
245 |
stopA = cA + PI;
|
230 |
246 |
centerA= angleMidpoint(pA,cA) + PI/2;
|
231 |
247 |
if( centerA>=2*PI ) centerA -= 2*PI;
|
232 |
248 |
float diff = centerA-cA;
|
... | ... | |
235 |
251 |
D = (float)((R-stroke)/Math.sin(alpha));
|
236 |
252 |
}
|
237 |
253 |
|
238 |
|
float sweepA = stopA-startA;
|
|
254 |
float sweepA = startA-stopA;
|
239 |
255 |
if( sweepA<0 ) sweepA += 2*PI;
|
|
256 |
sweepA = -sweepA;
|
240 |
257 |
|
241 |
258 |
float sinA = (float)(Math.sin(centerA));
|
242 |
259 |
float cosA = (float)(Math.cos(centerA));
|
243 |
|
float oX= currX - D*sinA;
|
244 |
|
float oY= currY + D*cosA;
|
|
260 |
float oX= cX + D*sinA;
|
|
261 |
float oY= cY + D*cosA;
|
245 |
262 |
|
246 |
263 |
startA *= 180/PI;
|
247 |
264 |
sweepA *= 180/PI;
|
248 |
265 |
|
249 |
266 |
if( !isConvex ) paint.setColor(color);
|
250 |
|
canvas.drawArc( left+oX-R, top+oY-R, left+oX+R, top+oY+R, startA, sweepA, false, paint);
|
|
267 |
canvas.drawArc( left+oX-R, bottom-oY-R, left+oX+R, bottom-oY+R, startA, sweepA, false, paint);
|
251 |
268 |
if( !isConvex ) paint.setColor(COLOR_STROKE);
|
252 |
269 |
}
|
253 |
270 |
|
254 |
271 |
///////////////////////////////////////////////////////////////////////////////////////////////////
|
255 |
272 |
// PUBLIC
|
256 |
273 |
|
257 |
|
public void drawRoundedPolygon(Canvas canvas, Paint paint, int left, int top, int color, ObjectSticker sticker)
|
|
274 |
public void drawRoundedPolygon(Canvas canvas, Paint paint, int left, int bottom, int color, ObjectSticker sticker)
|
258 |
275 |
{
|
259 |
276 |
float stroke = sticker.getStroke();
|
260 |
277 |
float[] vertices = sticker.getCoords();
|
... | ... | |
269 |
286 |
paint.setStyle(Paint.Style.FILL);
|
270 |
287 |
|
271 |
288 |
canvas.save();
|
272 |
|
canvas.clipRect(left,top,left+TEXTURE_HEIGHT,top+TEXTURE_HEIGHT);
|
273 |
|
canvas.drawRect(left,top,left+TEXTURE_HEIGHT,top+TEXTURE_HEIGHT,paint);
|
|
289 |
canvas.clipRect(left,bottom-TEXTURE_HEIGHT,left+TEXTURE_HEIGHT,bottom);
|
|
290 |
canvas.drawRect(left,bottom-TEXTURE_HEIGHT,left+TEXTURE_HEIGHT,bottom,paint);
|
274 |
291 |
|
275 |
292 |
paint.setColor(COLOR_STROKE);
|
276 |
293 |
paint.setStyle(Paint.Style.STROKE);
|
... | ... | |
290 |
307 |
|
291 |
308 |
for(int vert=0; vert<numVertices; vert++)
|
292 |
309 |
{
|
293 |
|
drawCurrSide(canvas,paint,left,top,stroke,prevX,prevY,currX,currY,prevA);
|
|
310 |
drawCurrSide(canvas,paint,left,bottom,stroke,prevX,prevY,currX,currY,prevA);
|
294 |
311 |
|
295 |
312 |
prevX = currX;
|
296 |
313 |
prevY = currY;
|
... | ... | |
324 |
341 |
|
325 |
342 |
for(int vert=0; vert<numVertices; vert++)
|
326 |
343 |
{
|
327 |
|
float prevAngle = computeSideAngle(currX-prevX,currY-prevY,-prevA);
|
328 |
|
float currAngle = computeSideAngle(nextX-currX,nextY-currY,+currA);
|
329 |
|
drawRoundCorner(canvas,paint,color,left,top,stroke,radii[vert],currX,currY,prevAngle,currAngle);
|
|
344 |
int prev = vert==0 ? numVertices-1 : vert-1;
|
|
345 |
float prevAngle = computeSideAngle(currX-prevX,currY-prevY,radii[prev],-prevA);
|
|
346 |
float currAngle = computeSideAngle(nextX-currX,nextY-currY,radii[vert],+currA);
|
|
347 |
drawRoundCorner(canvas,paint,color,left,bottom,stroke,radii[vert],currX,currY,prevAngle,currAngle);
|
330 |
348 |
|
331 |
349 |
prevX = currX;
|
332 |
350 |
prevY = currY;
|
FactorySticker: further improvements.