I created a function for drawing a circle in oepnGL java, and I want to rotate another circle on the circumference of a circle ?
This is my function for create circle, how to change it for drawing the circle on circumference?
For example create a new circle using as center coordinates points from first circle ?
private void rotateAroundOz(GL2 gl, int r, double cx, double cy) {
int step = 1;
gl.glLineWidth(5);
gl.glBegin(GL.GL_LINE_LOOP);
for (int i=0; i<360; i+=step) {
gl.glColor3d(1, 0, 0);
gl.glVertex2d(cx + r * Math.cos(Math.toRadians(i)), cy + r * Math.sin(Math.toRadians(i)));
}
gl.glEnd();
}
You just have to draw a circle (with rotateAroundOz()) using a position that you compute from
cx + r * Math.cos(Math.toRadians(i)), cy + r * Math.sin(Math.toRadians(i))
// This is the attributes of the invisible circle: "PositionCircle"
//that will gives you the circumference
float positionCircle_Radius = 1.0;
float positionCircle_CenterX = 0.0;
float positionCircle_CenterY = 0.0;
// This is actually the circle that you want to draw from the
// "PositionCircle"
int positionOnCircumferenceInDegrees = 90;
float drawnCircle_Radius = 2.0;
float drawnCircle_CenterX = positionCircle_CenterX + positionCircle_Radius * Math.cos(Math.toRadians(positionOnCircumferenceInDegrees));
float drawnCircle_CenterY = positionCircle_CenterY + positionCircle_Radius * Math.sin(Math.toRadians(positionOnCircumferenceInDegrees));
rotateAroundOz(gl, drawnCircle_Radius, drawnCircle_CenterX, drawnCircle_CenterY)
So you can add positionOnCircumferenceInDegrees and drawnCircle_Radius as parameters for your new function.
(That's my first response ever on SO :p hope it's comprehensible!)
Related
I can't seem to get the standard answer to work. I'm trying to find the new x,y coordinates of a point inside a larger rectangle, after rotating the larger rectangle around its center. (The end goal is to calculate the 4 corners of a collision box inside the larger rectangle.)
The rectangle is 50W x 128H, and the point inside the rectangle is at 15,111. If I rotate this same rectangle 90 degrees clockwise in Photoshop around its center, the point becomes 17,15 inside the rectangle that is now 128W and 50H.
However, if I use the formula I've found 100 times around here for the same question, I get a completely different answer.
import java.awt.*;
public class MyClass {
public static void main(String args[]) {
int width=50;
int height=128;
int cx = width/2;
int cy = height/2;
// should get 17,15
rotateXY(15,111,cx,cy,-90D); // returns 61,85, which is not even inside the image anymore
rotateXY(15,111,cx,cy,90D); // returns -11,66.
}
public static void rotateXY(int x, int y, int cx, int cy, double degrees) {
// x, y - coordinates of a corner point of the square
// cx, cy - center of square coordinates
double angle = Math.toRadians(degrees);
double x1 = x - cx;
double y1 = y - cy;
double x2 = x1 * Math.cos(angle) - y1 * Math.sin(angle);
double y2 = y1 * Math.cos(angle) + x1 * Math.sin(angle);
int rx = (int) x2 + cx;
int ry = (int) y2 + cy;
System.out.println(rx + "," + ry);
}
}
The method I used to rotate the image in java:
public static BufferedImage rotate(BufferedImage bimg, Double angle) {
double sin = Math.abs(Math.sin(Math.toRadians(angle))),
cos = Math.abs(Math.cos(Math.toRadians(angle)));
int w = bimg.getWidth();
int h = bimg.getHeight();
int neww = (int) Math.floor(w*cos + h*sin),
newh = (int) Math.floor(h*cos + w*sin);
BufferedImage rotated = new BufferedImage(neww, newh, bimg.getType());
Graphics2D graphic = rotated.createGraphics();
graphic.translate((neww-w)/2, (newh-h)/2);
graphic.rotate(Math.toRadians(angle), w/2, h/2);
graphic.drawRenderedImage(bimg, null);
graphic.dispose();
return rotated;
}
I assume you created an AffineTransform. With that you need three transformations:
translate the rectangle so it's center point is the origin
rotate the rectangle by some angle
translate the rectangle back to the position where it came from
Now with this you were able to transform the rectangle's coordinates (corners) into new screen coordinates. What you need is a transformation to get from new screen coordinates back to coordinates inside your rectangle. I think it looks like this:
translate the point the same as in step 1
rotate by the negative angle
undo step 1
These AffineTransforms can be applied quite efficiently, compared to your algorightm using trigonometry which even may have a limited range of validity.
See also Rotating Image with AffineTransform
I am having a bit of trouble trying to figure out how to draw paths from a point on a canvas with the start of each path being equally distanced from the initial point. To illustrate what I mean, the code that I have so far is able to generate this:
and the desired result is something like this:
My code:
int n = 3;
int r;
double x;
double y;
point1 = new Point(mWidth/2, mHeight/2);
double angle;
double angleFactor;
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for (int i = 0; i < 3; i++){
angleFactor = 2 * Math.PI / n;
angle = i * angleFactor;
x = (point1.x) + r * Math.cos(angle);
y = (point1.y) + r * Math.sin(angle);
//Draw paths
path.reset();
path.moveTo(point1.x, point1.y);
path.lineTo((float) x, (float) y);
canvas.drawPath(path, paint);
}
}
Is there a simple solution to this?
Since you want to have a tiny distance between the offset of a line and the center point, you can define start coordinates like this:
double xStart, xEnd;
double yStart, yEnd;
double offsetFraction = 0.1;
Inside the for loop in onDraw() :
double lengthX = r * Math.cos(angle);
double lengthY = r * Math.sin(angle);
xStart = (point1.x) + offsetFraction * lengthX;
yStart = (point1.y) + offsetFraction * lengthY;
xEnd = (point1.x) + lengthX;
yEnd = (point1.y) + lengthY;
//Draw paths
path.reset();
path.moveTo((float) xStart, (float) yStart);
path.lineTo((float) xEnd, (float) yEnd);
canvas.drawPath(path, paint);
I have a color circle where the user can choose a color from. The color is calculated with this method
public int getColorForPoint(int x, int y, float[] hsv) {
x -= fullCircleRadius;
y -= fullCircleRadius;
double centerDist = Math.sqrt(x * x + y * y);
hsv[0] = (float) (Math.atan2(y, x) / Math.PI * 180f) + 180;
hsv[1] = Math.max(0f, Math.min(1f, (float) (centerDist / innerCircleRadius)));
return Color.HSVToColor(hsv);
}
Now I need the reversed method to calculate the x and y coordinate by a given color (hsv array).
To be more specific: The user can save a color and the indicator in the color circle should "jump" to the saved color on the circle.
But I'm quite lost with this mathematics.
Looking at the way you calculate centerDist - I can tell your circle centre is at the origin (0,0).
Basically HSV is a polar co ordinate, all you need is to convert a polar co ordinate to cartesian co ordinate. which is done as follows.
public double[] getHSVtoCartesian(double[] hsv) {
double [] xy;
double theta = hsv[0];
double r = hsv[1];
xy[0] = r * Math.cos(theta);
xy[1] = r * Math.sin(theta);
return xy;
}
I am using Bresenham line algorithm in order to draw a simple line.
I need help with using this algorithm to create a polygon with equal sides and angles.
The sides will be the line created by the Bresenham algorithm, but how do I use the created line in order to draw a polygon with X number of sides and equal angels?
Here is the line algorithm I am using:
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.RED);
for (double t = 0; t < 1; t += 0.01) {
Point2D p = between(p1, p2, t);
g2d.fillRect((int)p.getX(), (int)p.getY(), 5, 5);
}
g2d.dispose();
}
public Point2D between(Point p1, Point p2, double time) {
double deltaX = p2.getX() - p1.getX();
double deltaY = p2.getY() - p1.getY();
double x = p1.getX() + time * deltaX;
double y = p1.getY() + time * deltaY;
return new Point2D.Double(x, y);
}
Thanks in advance.
Let's suppose your (i-1)th edge of N-sided polygon ends at point x(i-1), y(i-1) and is rotated at angle a(i-1) relative to horizontal axis. So the next edge will be rotated at the angle:
a(i) = a(i-1) + pi - (N-2)/N*pi
and will end at the point:
x(i) = x(i-1) + L * cos(a(i))
y(i) = y(i-1) + L * sin(a(i))
where L is length of one edge. So iterating i from 1 to N and connecting points, you will get your polygon.
If you want to build your polygon using its center point x(c), y(c) and radius R of containing circle, calculate point coordinates in the following way:
x(i) = x(c) + R * cos(2*pi*i/N)
y(i) = y(c) + R * sin(2*pi*i/N)
I Have Some problem.
Let's say I have Q Icons (simple icon let say android logo) and I want to place them in a star topology against the single star center (icons) and connecting them on android canvas.
How can I do it?
any exact Links?
any algorithm information?
Essentially what you will want to do is create points around a centre, give the points an icon and a line connecting them with the centre.
Creating 2d points on a circle can be done with cosine/sine:
double angle;
point.x = offsetX + radius*Math.cos(angle);
point.y = offsetY + radius*Math.sin(angle);
Increment the angle with a suitable value for each contact and store points like this in an array or a list.
When it comes to drawing, draw your icon centred at its point (yourCanvas.drawBitmap()), and draw a line to the centre point (yourCanvas.drawLine()).
public void starTopology(Canvas mCanvas,int noOfFriends,float centerX,float centerY,int radious) {
final double PI = 3.14;
final double MARGIN = (2*PI)/noOfFriends;
final double OFFSETX = centerX;
final double OFFSETY = centerY;
final int RADIUS = radious;
float pointXCoord = 0;
float pointYCoord = 0;
double NextPositionOnCircumference = MARGIN;
Paint myCustomizedBrush = new Paint();
myCustomizedBrush.setAntiAlias(true);
myCustomizedBrush.setColor(Color.WHITE);
for(int i= 0; i < noOfFriends; i++){
pointXCoord = (float) (OFFSETX + RADIUS * Math.cos(NextPositionOnCircumference));
pointYCoord = (float) (OFFSETY + RADIUS * Math.sin(NextPositionOnCircumference));
NextPositionOnCircumference += MARGIN;
mCanvas.drawLine((float)OFFSETX, (float)OFFSETY, pointXCoord, pointYCoord, myCustomizedBrush);
pointXCoord -= 10;
pointYCoord -= 10;
mCanvas.drawBitmap(Utility.FriendProfilePic.get(i), pointXCoord, pointYCoord, null);
}
mCanvas.drawCircle((float)OFFSETX, (float)OFFSETY, 5, myCustomizedBrush);
}