Android How to draw triangles inside a hexagon? - android

First thing I have drawn the three lines of the hexagon width specific width then I have drawn the six points using this formula section = 2 * PI / NumberOfPoints. Here is the pic of lines I have drawn:
what I want is to draw a triangle between every two lines which will be 6 triangles. Here is the pic when I drew the triangles:
My problem is I want the triangle to be drawn between the lines, not above them which mean the triangle should not overlaps the line.
Here is how I drew the lines:
for (int i = 1; i <= 6; i++) {
float eX = (float) (x + radius * Math.cos(section * i));
float eY = (float) (y + radius * Math.sin(section * i));
linesPaint.setShader(new LinearGradient(x, y, eX, eY, Color.BLACK, Color.TRANSPARENT, Shader.TileMode.MIRROR));
canvas.drawLine(x, y, eX, eY, linesPaint);
}
and here is how I drew the triangles
for (int i = 1; i <= 6; i++) {
TriangleColor triangleColor = triangleColors.get(i - 1);
trianglesPaint.setShader(new LinearGradient(0, 0, 0, getHeight(), triangleColor.firstColor, triangleColor.secondColor, Shader.TileMode.REPEAT));
float x1 = (float) (x + radius * Math.cos(section * i));
float y1 = (float) (y + radius * Math.sin(section * i));
float x2 = (float) (x + radius * Math.cos(section * (i + 1)));
float y2 = (float) (y + radius * Math.sin(section * (i + 1)));
trianglesPath.moveTo(x, y);
trianglesPath.lineTo(x1, y1);
trianglesPath.lineTo(x2, y2);
trianglesPath.lineTo(x, y);
canvas.drawPath(trianglesPath, trianglesPaint);
trianglesPath.reset();
}
Can anyone help me with the formula? Thanks in advance.

I assume that you have lines with thickness 2d
To avoid overwriting these lines, you can shift the central point for every triangle by dstance d/sin(30) = 2*d in direction of bisector between two lines
Perhaps also you need to diminish radius (length of triangle side along the line)
newradius = radius - d*sqrt(3) - d * sqrt(3)/3
for (int i = 1; i <= 6; i++) {
cx = x + 2 * d * Math.cos(section * (i + 0.5));
cy = x + 2 * d * Math.sin(section * (i + 0.5));
float x1 = (float) (cx + newradius * Math.cos(section * i)); /
//and similar for other coordinates
trianglesPath.moveTo(cx, cy);
trianglesPath.lineTo(x1, y1);
...

Related

android canvas draw text on circle radius based

I need to make lucky wheel like view, and there texts are drawn regarding the radius, as you can see image below. ( there you can see red line, I want to draw texts along that red line )
This is the result I want to achieve but, right now with my method, it just draws text based on circle like below
private void drawText(Canvas canvas, float tempAngle, float sweepAngle, String text) {
Path path = new Path();
Log.d("mytag", "tempAngle = " + tempAngle + ", sweepAngle = " + sweepAngle);
path.addArc(range, tempAngle, sweepAngle);
float textWidth = textPaint.measureText(text);
int hOffset = (int) (radius * Math.PI / mWheelItems.size() / 2 - textWidth / 2);
int vOffset = (radius / 2 / 3) - 15; // here 15 is distance from image
canvas.drawTextOnPath(text, path, hOffset, vOffset, textPaint);
}
Instead of creating an arc to draw the text on, you need a path from the outside of the circle to the center. I think you need something like this
int radius = 180;
float centerX = width/2f;
float centerY = height/2f
double radians = radius * Math.PI / 180;
float x = (float)Math.sin(radians);
float y = (float)-Math.cos(radians);
Path path = new Path();
path.moveTo(x,y);
path.lineTo(centerX, centerY);
canvas.drawTextOnPath(text, path, hOffset, vOffset, textPaint);
First, find the slice centre points.
Kotlin sample snippet
val arcCenter = startAngle + (arcProgress / 2)
//middle point radius is half of the radius of the circle
val pointRadius = size.width / 4
/*Calculate the x & y coordinates
* find points using angle and radius
*https://en.wikipedia.org/wiki/Polar_coordinate_system#Converting_between_polar_and_Cartesian_coordinates
* */
val x =
(pointRadius * cos(Math.toRadians(arcCenter.toDouble()))) +
size.center.x
val y =
(pointRadius * sin(Math.toRadians(arcCenter.toDouble()))) +
size.center.y
Then Rotate your canvas to the arch centre angle, Draw your text and restore the canvas to a normal position
it.nativeCanvas.rotate( arcCenter, x, y)
it.nativeCanvas.drawText(...)
it.nativeCanvas.rotate( -arcCenter, x, y)

How to create dripping Spray can tool for Graffiti app in Android

I am trying to create a spray can tool in Android for a Graffiti app. I want to achieve something similar done in the below image
Dripping Spray Can Sample image
Requirements: If somebody is spraying the can then it should drip some color downwards while drawing a spray line
I am currently using the following code, but not getting the correct results:
if (bufferPaint == null) {
bufferPaint = new Paint();
bufferPaint.setAntiAlias(true);
bufferPaint.setDither(true);
bufferPaint.setXfermode(null);
if (mPaint == null)
setupColor(0f, 100f);
}
int alpha = Math.round((float) 100 / 100 * 255);
bufferPaint.setAlpha(alpha);
private void paintOneDab(float x, float y) {
float radius = 5 / 2f;
float scatter = 500 / 100f;
x += radius 2 scatter (1 - 2 (float) Math.random());
y += radius 2 scatter (1 - 2 (float) Math.random());
float hardness = 20 / 100f;
positions[0] = 0;
positions[1] = (float) (Math.sqrt(hardness));
positions[2] = 1;
bufferPaint.setShader(new RadialGradient(x, y, radius, colors, positions, Shader.TileMode.CLAMP));
mCanvas.save();
int angle = 180;
mCanvas.rotate(angle, x, y);
int roundness = 100;
mCanvas.scale(1f, 100f / roundness, x, y);
mCanvas.drawCircle(x, y, radius, bufferPaint);
mCanvas.restore();
}

image deformation in an android project

In my android app, I need to deform the image from one point to the other point.
It should seems like that
the origin point A and the B is the new position of A
the result may like that
I have try to use the "drawBitmapMesh" function to make it possible, but did not reach, here is the wrap code:
public void warp(float startX, float startY, float endX, float endY) {
float ddPull = (endX - startX) * (endX - startX) + (endY - startY) * (endY - startY);
float dPull = (float) Math.sqrt(ddPull);
for (int i = 0; i < (COUNTS * 2); i += 2) {
float dx = orig[i] - startX;
float dy = orig[i + 1] - startY;
float dd = dx * dx + dy * dy;
float d = (float) Math.sqrt(dd);
// do deformation when the point is in the circle
if (d < cirR) {
double e =(cirR * cirR - dd) * (cirR * cirR - dd) / ((cirR * cirR - dd + dPull * dPull) * (cirR * cirR - dd + dPull * dPull));
double pullX = e * (endX - startX);
double pullY = e * (endY - startY);
verts[i] = (float) (orig[i] + pullX);
verts[i + 1] = (float) (orig[i + 1] + pullY);
}
}
invalidate();
}
At last I solve it by myself, i use the GPUimage for Android and write a customized filter by GLSL, it works good~!

Android View Invalidate optimization idea

I'm trying to make an animation on my android application.
I have a list of View I want to draw every 10 ms to have a smooth animations.
class CircularAnimationSector extends View{
private double scale;
private double circularPosition;
private double circularLength;
private double sectionRadiusRatio;
private double circularSpeed;
private int color;
private Paint paint = new Paint();
private ICircular iCircular;
#Override
public void draw(Canvas canvas) {
super.draw(canvas);
Path path = new Path();
int width = this.getWidth();
// int height = this.getHeight();
Point center = new Point((int)(width / 2.0f), (int)(width / 2.0f));
int innerWidthRadius = (int) (this.iCircular.GetViewSize() / 2.0f);
float startRadius = (float)(innerWidthRadius * this.iCircular.GetStartRatio());
float endRadius = (float)(startRadius + this.scale * (this.sectionRadiusRatio - this.iCircular.GetStartRatio()) * innerWidthRadius);
float startAngle = (float)(this.circularPosition - this.circularLength / 2.0f);
float endAngle = (float)(this.circularPosition + this.circularLength / 2.0f);
Point p1 = new Point((int) (center.x + startRadius * Math.cos(startAngle)), (int) (center.y + startRadius * Math.sin(startAngle)));
Point p3 = new Point((int) (center.x + endRadius * Math.cos(endAngle)), (int) (center.y + endRadius * Math.sin(endAngle)));
// PATH DRAWING
path.moveTo((float) (p1.x), (float) (p1.y));
path.arcTo(new RectF(center.x - startRadius, center.y - startRadius, center.x + startRadius, center.y + startRadius), (float) (startAngle * 180 / Math.PI), (float) ((endAngle - startAngle) * 180 / Math.PI));
path.lineTo((float) (p3.x), (float) (p3.y));
path.arcTo(new RectF(center.x - endRadius, center.y - endRadius, center.x + endRadius, center.y + endRadius), (float) (endAngle * 180 / Math.PI), (float) ((startAngle - endAngle) * 180 / Math.PI));
path.lineTo((float) (p1.x), (float) (p1.y));
canvas.drawPath(path, this.paint);
this.circularPosition += this.circularSpeed;
}
}
But it seems that the animation is not as smooth as expected and the application lag a little.
Do you have any advice to optimize my animation ?
I just want to draw a view every 10 ms (for instance) and then upadte its position and draw it again around a circle.

android 3d vertical carousel view

I am using http://www.codeproject.com/Articles/146145/Android-3D-Carousel code to create a vertical carousel view.i can see the vertical carousel using below changes in the code but center item is not properly placed in the screen and if the list items size increased, diameter moves upwards.
private void setUpChild(CarouselImageView child, int index, float angleOffset) {
// Ignore any layout parameters for child, use wrap content
addViewInLayout(child, -1 /*index*/, generateDefaultLayoutParams());
child.setSelected(index == mSelectedPosition);
int h;
int w;
if (mInLayout)
{
h = (getMeasuredHeight() - getPaddingBottom()-getPaddingTop())/3;
w = getMeasuredWidth() - getPaddingLeft() - getPaddingRight()/3;
}
else
{
h = (getMeasuredHeight() - getPaddingBottom()-getPaddingTop())/3;
w = getMeasuredWidth() - getPaddingLeft() - getPaddingRight()/3;
}
child.setCurrentAngle(angleOffset);
// modify the diameter.
Calculate3DPosition(child, w*(getAdapter().getCount()/4), angleOffset);
// Measure child
child.measure(w, h);
int childLeft;
// Position vertically based on gravity setting
int childTop = calculateTop(child, true);
childLeft = 0;
child.layout(childLeft, childTop, w, h);
}
change in calculate3position function as below
float x = (float) (-diameter/2 * Math.cos(angleOffset) * 0.00001);
float z = diameter/2 * (1.0f - (float)Math.cos(angleOffset));
float y = (float) (diameter/2 * Math.sin(angleOffset)) + diameter/2 - child.getWidth();
child.setX(x);
child.setZ(z);
child.setY(y);
I think that this calculation:
float x = (float) (-diameter/2 * Math.cos(angleOffset) * 0.00001);
float z = diameter/2 * (1.0f - (float)Math.cos(angleOffset));
float y = (float) (diameter/2 * Math.sin(angleOffset)) + diameter/2 - child.getWidth();
should be this:
float x = 0.0f
float z = diameter/2.0f * (1.0f - (float)Math.cos(angleOffset));
float y = (diameter/2.0f * Math.sin(angleOffset)) + diameter/2.0f - child.getHeight()/2.0f;
Your x position should always be zero, and your y position should be based on the sin, and should be offset by 1/2 of the height of the child instead of 1/2 of the width.
Hello try this code and replace with this code in your Calculate3DPosition method
angleOffset = angleOffset * (float) (Math.PI / 180.0f);
float y = (float) (((diameter * 60) / 100) * Math.sin(angleOffset)) + ((diameter * 50) / 100);
float z = diameter / 2 * (1.0f - (float) Math.cos(angleOffset));
float x = (float) (((diameter * 5) / 100) * Math.cos(angleOffset) * 0.3);
child.setItemX(x);
child.setItemZ((z * 30) / 100);
child.setItemY(-(y));
its solve my problem please try this one

Categories

Resources