I designed a simple java program viewing 3D Cube, but i do not why i guess there is something illogically in that.
the length of rib = 350
the front square depth (z axis) is 0
the back square depth (z axis) is equal to the length of rib,
but the result was very tall cube !!:
I designed a simple java program viewing 3D Cube, but i do not why i guess there is something illogically in that.
the length of rib = 350
the front square depth (z axis) is 0
the back square depth (z axis) is equal to the length of rib,
but the result was very tall cube !!:
The code:
public void paint(Graphics g){
super.paint(g);
int squareLengthRib = 350; // Ribs length
int frontSquareDepth = 0; // Z value (Depth of front square)
int backSquareDepth = frontSquareDepth + squareLengthRib; // Z value (Depth of back square)
x1 = 300;
y1 = 300;
z1 = frontSquareDepth;
x2 = x1 + squareLengthRib;
y2 = y1 ;
z2 = z1;
x3 = x2;
y3 = y2 + squareLengthRib;
z3 = z2;
x4 = x1;
y4 = y3;
z4 = z3;
/**********************************************/
x5 = x1;
y5 = y1;
z5 = backSquareDepth;
x6 = x2;
y6 = y2;
z6 = z5;
x7 = x3;
y7 = y3;
z7 = z6;
x8 = x4;
y8 = y4;
z8 = z7;
PerspectiveProjection();
g.drawLine((int)x1, (int)y1, (int)x2, (int)y2);
g.drawLine((int)x2, (int)y2, (int)x3, (int)y3);
g.drawLine((int)x3, (int)y3, (int)x4, (int)y4);
g.drawLine((int)x4, (int)y4, (int)x1, (int)y1);
g.drawLine((int)x5, (int)y5, (int)x6, (int)y6);
g.drawLine((int)x6, (int)y6, (int)x7, (int)y7);
g.drawLine((int)x7, (int)y7, (int)x8, (int)y8);
g.drawLine((int)x8, (int)y8, (int)x5, (int)y5);
g.drawLine((int)x1, (int)y1, (int)x5, (int)y5);
g.drawLine((int)x2, (int)y2, (int)x6, (int)y6);
g.drawLine((int)x3, (int)y3, (int)x7, (int)y7);
g.drawLine((int)x4, (int)y4, (int)x8, (int)y8);
}
private void PerspectiveProjection() {
double d = 100;
double xd, yd;
xd = (x1 * d) / (z1 + d);
yd = (y1 * d) / (z1 + d);
x1 = xd;
y1 = yd;
xd = (x2 * d) / (z2 + d);
yd = (y2 * d) / (z2 + d);
x2 = xd;
y2 = yd;
xd = (x3 * d) / (z3 + d);
yd = (y3 * d) / (z3 + d);
x3 = xd;
y3 = yd;
xd = (x4 * d) / (z4 + d);
yd = (y4 * d) / (z4 + d);
x4 = xd;
y4 = yd;
xd = (x5 * d) / (z5 + d);
yd = (y5 * d) / (z5 + d);
x5 = xd;
y5 = yd;
xd = (x6 * d) / (z6 + d);
yd = (y6 * d) / (z6 + d);
x6 = xd;
y6 = yd;
xd = (x7 * d) / (z7 + d);
yd = (y7 * d) / (z7 + d);
x7 = xd;
y7 = yd;
xd = (x8 * d) / (z8 + d);
yd = (y8 * d) / (z8 + d);
x8 = xd;
y8 = yd;
}
Related
I'm currently programming a 3D software renderer where I am rasterizing triangles based on a function to take x and y coordinates to draw 3 lines to draw a triangle that works just fine. However, my code to interpolate through the triangle to fill it with the color of a BufferedImage is very costly and eats at the performance of my application. I was informed that instantiating a new Color object and using the drawLine() method to draw a pixel to the screen is very costly on the CPU. Is there any alternative to this drawing routine such as holding all possible RGB's/pixels on the screen in an array and calling from that to draw to the screen to limit the number of pixels drawn?
public static void drawTriangle(Graphics2D g2, double x1, double y1, double x2, double y2, double x3, double y3)
{
g2.setStroke(new BasicStroke(2));
g2.draw(new Line2D.Double(x1, y1, x2, y2));
g2.draw(new Line2D.Double(x2, y2, x3, y3));
g2.draw(new Line2D.Double(x3, y3, x1, y1));
}
public static void texturedTriangle(Graphics2D g2, int x1, int y1, double u1, double v1, int x2, int y2, double
u2, double v2, int x3, int y3, double u3, double v3, BufferedImage img, double visibility, boolean fog)
{
if(y2 < y1)
{
int temp = y1;
y1 = y2;
y2 = temp;
int tempx = x1;
x1 = x2;
x2 = tempx;
double tempu = u1;
u1 = u2;
u2 = tempu;
double tempv = v1;
v1 = v2;
v2 = tempv;
}
if(y3 < y1)
{
int temp = y1;
y1 = y3;
y3 = temp;
int tempx = x1;
x1 = x3;
x3 = tempx;
double tempu = u1;
u1 = u3;
u3 = tempu;
double tempv = v1;
v1 = v3;
v3 = tempv;
}
if(y3 < y2)
{
int temp = y2;
y2 = y3;
y3 = temp;
int tempx = x2;
x2 = x3;
x3 = tempx;
double tempu = u2;
u2 = u3;
u3 = tempu;
double tempv = v2;
v2 = v3;
v3 = tempv;
}
int dy1 = y2 - y1;
int dx1 = x2 - x1;
double dv1 = v2 - v1;
double du1 = u2 - u1;
int dy2 = y3 - y1;
int dx2 = x3 - x1;
double dv2 = v3 - v1;
double du2 = u3 - u1;
double tex_u, tex_v;
double dax_step = 0, dbx_step = 0, du1_step = 0, dv1_step = 0, du2_step = 0, dv2_step = 0;
if (dy1 != 0) dax_step = dx1 / (float)Math.abs(dy1);
if (dy2 != 0) dbx_step = dx2 / (float)Math.abs(dy2);
if (dy1 != 0) du1_step = du1 / (float)Math.abs(dy1);
if (dy1 != 0) dv1_step = dv1 / (float)Math.abs(dy1);
if (dy2 != 0) du2_step = du2 / (float)Math.abs(dy2);
if (dy2 != 0) dv2_step = dv2 / (float)Math.abs(dy2);
if(dy1 != 0)
{
for(int i = y1; i <= y2; i++)
{
int ax = (int)(x1 + (i - y1) * dax_step);
int bx = (int)(x1 + (i - y1) * dbx_step);
double tex_su = u1 + (float)(i - y1) * du1_step;
double tex_sv = v1 + (float)(i - y1) * dv1_step;
double tex_eu = u1 + (float)(i - y1) * du2_step;
double tex_ev = v1 + (float)(i - y1) * dv2_step;
if(ax > bx)
{
int temp = ax;
ax = bx;
bx = temp;
double temps = tex_su;
tex_su = tex_eu;
tex_eu = temps;
double tempv = tex_sv;
tex_sv = tex_ev;
tex_ev = tempv;
}
tex_u = tex_su;
tex_v = tex_sv;
double tstep = 1.0 / (float)(bx-ax);
double t = 0.0;
for(int j = ax; j < bx; j++)
{
tex_u = (1.0 - t) * tex_su + t * tex_eu;
tex_v = (1.0 - t) * tex_sv + t * tex_ev;
Color background = Color.black;
Color col = new Color(img.getRGB(
(int)Math.max(0,tex_u*(img.getWidth()-1)),
(int)Math.max(0,tex_v*(img.getHeight()-1))
));
col = blend(background, col,(float)visibility);
if(fog)
{
g2.setColor(col);
}
else
{
g2.setColor(new Color(img.getRGB(
(int)Math.max(0,tex_u*(img.getWidth()-1)),
(int)Math.max(0,tex_v*(img.getHeight()-1))
)));
}
g2.drawLine(j, i, j+1, i+1);
t += tstep;
}
}
}
dy1 = y3 - y2;
dx1 = x3 - x2;
dv1 = v3 - v2;
du1 = u3 - u2;
if (dy1 != 0) dax_step = dx1 / (float)Math.abs(dy1);
if (dy2 != 0) dbx_step = dx2 / (float)Math.abs(dy2);
du1_step = 0; dv1_step = 0;
if (dy1 != 0) du1_step = du1 /(float)Math.abs(dy1);
if (dy1 != 0) dv1_step = dv1 / (float)Math.abs(dy1);
if(dy1 != 0)
{
for(int i = y2; i <= y3; i++)
{
int ax = (int)(x2 + (float)(i - y2) * dax_step);
int bx = (int)(x1 + (float)(i - y1) * dbx_step);
double tex_su = u2 + (float)(i - y2) * du1_step;
double tex_sv = v2 + (float)(i - y2) * dv1_step;
double tex_eu = u1 + (float)(i - y1) * du2_step;
double tex_ev = v1 + (float)(i - y1) * dv2_step;
if(ax > bx)
{
int temp = ax;
ax = bx;
bx = temp;
double temps = tex_su;
tex_su = tex_eu;
tex_eu = temps;
double tempv = tex_sv;
tex_sv = tex_ev;
tex_ev = tempv;
}
tex_u = tex_su;
tex_v = tex_sv;
double tstep = 1.0/ (float)(bx-ax);
double t = 0.0;
for(int j = ax; j < bx; j++)
{
tex_u = (1.0 - t) * tex_su + t * tex_eu;
tex_v = (1.0 - t) * tex_sv + t * tex_ev;
Color background = Color.black;
Color col = new Color(img.getRGB(
(int)Math.max(0,tex_u*(img.getWidth()-1)),
(int)Math.max(0,tex_v*(img.getHeight()-1))
));
col = blend(background, col,(float)visibility);
if(fog)
{
g2.setColor(col);
}
else
{
g2.setColor(new Color(img.getRGB(
(int)Math.max(0,tex_u*(img.getWidth()-1)),
(int)Math.max(0,tex_v*(img.getHeight()-1))
)));
}
g2.drawLine(j, i, j+1, i+1);
t += tstep;
}
}
}
}
public static Color blend( Color c1, Color c2, float ratio )
{
if ( ratio > 1f ) ratio = 1f;
else if ( ratio < 0f ) ratio = 0f;
float iRatio = 1.0f - ratio;
int i1 = c1.getRGB();
int i2 = c2.getRGB();
int a1 = (i1 >> 24 & 0xff);
int r1 = ((i1 & 0xff0000) >> 16);
int g1 = ((i1 & 0xff00) >> 8);
int b1 = (i1 & 0xff);
int a2 = (i2 >> 24 & 0xff);
int r2 = ((i2 & 0xff0000) >> 16);
int g2 = ((i2 & 0xff00) >> 8);
int b2 = (i2 & 0xff);
int a = (int)((a1 * iRatio) + (a2 * ratio));
int r = (int)((r1 * iRatio) + (r2 * ratio));
int g = (int)((g1 * iRatio) + (g2 * ratio));
int b = (int)((b1 * iRatio) + (b2 * ratio));
return new Color( a << 24 | r << 16 | g << 8 | b );
}
}
I'm trying to draw Pie chart with PDFbox, but there are white lines between the slices, could anyone help me with this? is there an option for this?
Attached the code for drawing the arc that I'm using:
while (start < stop) {
List<Float> smallArc = PdfUtils.createSmallArc(a, b, radius, start, start +
2.0944 > stop ? stop : start + 2.0944);
contentStream.saveGraphicsState();
contentStream.setNonStrokingColor(components[0], components[1],
components[2]);
contentStream.moveTo(smallArc.get(0), smallArc.get(1));
contentStream.curveTo(smallArc.get(2), smallArc.get(3), smallArc.get(4),
smallArc.get(5), smallArc.get(6), smallArc.get(7));
contentStream.fill();
contentStream.restoreGraphicsState();
start += 2.0944;
}
public static List<Float> createSmallArc(float x, float y, double r, double a1, double a2) {
double a = (a2 - a1) / 2;
double x4 = r * Math.cos(a);
double y4 = r * Math.sin(a);
double x1 = x4;
double y1 = -y4;
double q1 = x1 * x1 + y1 * y1;
double q2 = q1 + x1 * x4 + y1 * y4;
double k2 = 4 / 3d * (Math.sqrt(2 * q1 * q2) - q2) / (x1 * y4 - y1 * x4);
double x2 = x1 - k2 * y1;
double y2 = y1 + k2 * x1;
double x3 = x2;
double y3 = -y2;
double ar = a + a1;
double cos_ar = Math.cos(ar);
double sin_ar = Math.sin(ar);
List<Float> list = new ArrayList<Float>();
list.add((float) (r * Math.cos(a1)) + x);
list.add((float) -(r * Math.sin(a1)) + y);
list.add((float) (x2 * cos_ar - y2 * sin_ar) + x);
list.add((float) -(x2 * sin_ar + y2 * cos_ar) + y);
list.add((float) (x3 * cos_ar - y3 * sin_ar) + x);
list.add((float) -(x3 * sin_ar + y3 * cos_ar) + y);
list.add((float) (r * Math.cos(a2)) + x);
list.add((float) -(r * Math.sin(a2)) + y);
return list;
}
Attached image of the result:
Thanks
Instead of using fill(), use the fillAndStroke() method and call setStrokingColor() with the same parameters that you used for setNonStrokingColor().
I have a cube that rotates on its 3 axis, when key[a] == true it will spin to the left as if it was rolling that way. rotating the cube 45 degrees in any direction sets it back 90 degrees for the illusion of continuing. this maintains 3 axis that are < 45 degrees off from the environment
I believe this is correct but the x axis for the cube seems to be relative to the environment while y and z are relative to the cubes orientation, I can not find reference to this in the documentation is it a bug?
https://processing.org/reference/rotateY_.html
https://processing.org/reference/rotateX_.html
if(keys[w]) {
if (x >= 359) x = 0;
x = x + 1;
}
if(keys[a]) {
if (z >= 359) z = 0;
z = z + 1;
}
if(keys[s]) {
if (x <= 0) x = 359;
x = x - 1;
}
if(keys[d]) {
if (z <= 0) z = 359;
z = z - 1;
}
// return 90 deg for magic trick
if (x > 45 && x < 180) x = 270 + x;
if (x < 316 && x > 180) x = 360 - x;
if (y > 45 && y < 180) y = 270 + y;
if (y < 316 && y > 180) y = 360 - y;
Matrix transformations are not commutative. The order matters. The matrix operations like rotate() specify a new matrix and multiply the current matrix by the new matrix.
Hence, there is a difference between doing this
rotateX(x);
rotateY(y);
rotateZ(z);
and doing that
rotateZ(z);
rotateY(y);
rotateX(x);
And
rotateX(x1 + x2);
rotateY(y1 + y2);
rotateZ(z1 + z2);
is not the same as
rotateX(x1);
rotateY(y1);
rotateZ(z1);
rotateX(x2);
rotateY(y2);
rotateZ(z2);
One possible solution to your problem would be to use Quaternions. Quaternions behave differently than Euler angles and have also no Gimbal lock issue. Processing use OpenGL under the hood and doesn't support quaternions. However a quaternion can be transformed to a matrix and a matrix can be applied by applyMatrix().
I found this ArcBall example that dose exactly what I wanted. just added a modification to work with keys instead of mouse drag.
ArcBall with mod
// Ariel and V3ga's arcball class with a couple tiny mods by Robert Hodgin & more by me
class Arcball {
float center_x, center_y, radius;
Vec3 v_down, v_drag;
Quat q_now, q_down, q_drag;
Vec3[] axisSet;
int axis;
float mxv, myv;
float x, y;
Arcball(float center_x, float center_y, float radius){
this.center_x = center_x;
this.center_y = center_y;
this.radius = radius;
v_down = new Vec3();
v_drag = new Vec3();
q_now = new Quat();
q_down = new Quat();
q_drag = new Quat();
axisSet = new Vec3[] {new Vec3(1.0f, 0.0f, 0.0f), new Vec3(0.0f, 1.0f, 0.0f), new Vec3(0.0f, 0.0f, 1.0f)};
axis = -1; // no constraints...
}
void rollforward(){
q_down.set(q_now);
v_down = XY_to_sphere(center_x, center_y);
q_down.set(q_now);
q_drag.reset();
v_drag = XY_to_sphere(center_x, center_y - 10);
q_drag.set(Vec3.dot(v_down, v_drag), Vec3.cross(v_down, v_drag));
}
void rolldown(){
q_down.set(q_now);
v_down = XY_to_sphere(center_x, center_y);
q_down.set(q_now);
q_drag.reset();
v_drag = XY_to_sphere(center_x, center_y + 10);
q_drag.set(Vec3.dot(v_down, v_drag), Vec3.cross(v_down, v_drag));
}
void rollleft(){
q_down.set(q_now);
v_down = XY_to_sphere(center_x + radius, center_y + radius);
q_down.set(q_now);
q_drag.reset();
v_drag = XY_to_sphere(center_x + 10 * PI + radius, center_y + radius);
q_drag.set(Vec3.dot(v_down, v_drag), Vec3.cross(v_down, v_drag));
}
void rollright(){
q_down.set(q_now);
v_down = XY_to_sphere(center_x + radius, center_y + radius);
q_down.set(q_now);
q_drag.reset();
v_drag = XY_to_sphere(center_x - 10 * PI + radius, center_y + radius);
q_drag.set(Vec3.dot(v_down, v_drag), Vec3.cross(v_down, v_drag));
}
void mousePressed(){
v_down = XY_to_sphere(mouseX, mouseY); // when m pressed
q_down.set(q_now);
q_drag.reset();
}
void mouseDragged(){
v_drag = XY_to_sphere(mouseX, mouseY);
q_drag.set(Vec3.dot(v_down, v_drag), Vec3.cross(v_down, v_drag));
}
void run(){
q_now = Quat.mul(q_drag, q_down);
applyQuat2Matrix(q_now);
x += mxv;
y += myv;
mxv -= mxv * .01;
myv -= myv * .01;
}
Vec3 XY_to_sphere(float x, float y){
Vec3 v = new Vec3();
v.x = (x - center_x) / radius;
v.y = (y - center_y) / radius;
float mag = v.x * v.x + v.y * v.y;
if (mag > 1.0f){
v.normalize();
} else {
v.z = sqrt(1.0f - mag);
}
return (axis == -1) ? v : constrain_vector(v, axisSet[axis]);
}
Vec3 constrain_vector(Vec3 vector, Vec3 axis){
Vec3 res = new Vec3();
res.sub(vector, Vec3.mul(axis, Vec3.dot(axis, vector)));
res.normalize();
return res;
}
void applyQuat2Matrix(Quat q){
// instead of transforming q into a matrix and applying it...
float[] aa = q.getValue();
rotate(aa[0], aa[1], aa[2], aa[3]);
}
}
static class Vec3{
float x, y, z;
Vec3(){
}
Vec3(float x, float y, float z){
this.x = x;
this.y = y;
this.z = z;
}
void normalize(){
float length = length();
x /= length;
y /= length;
z /= length;
}
float length(){
return (float) Math.sqrt(x * x + y * y + z * z);
}
static Vec3 cross(Vec3 v1, Vec3 v2){
Vec3 res = new Vec3();
res.x = v1.y * v2.z - v1.z * v2.y;
res.y = v1.z * v2.x - v1.x * v2.z;
res.z = v1.x * v2.y - v1.y * v2.x;
return res;
}
static float dot(Vec3 v1, Vec3 v2){
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
}
static Vec3 mul(Vec3 v, float d){
Vec3 res = new Vec3();
res.x = v.x * d;
res.y = v.y * d;
res.z = v.z * d;
return res;
}
void sub(Vec3 v1, Vec3 v2){
x = v1.x - v2.x;
y = v1.y - v2.y;
z = v1.z - v2.z;
}
}
static class Quat{
float w, x, y, z;
Quat(){
reset();
}
Quat(float w, float x, float y, float z){
this.w = w;
this.x = x;
this.y = y;
this.z = z;
}
void reset(){
w = 1.0f;
x = 0.0f;
y = 0.0f;
z = 0.0f;
}
void set(float w, Vec3 v){
this.w = w;
x = v.x;
y = v.y;
z = v.z;
}
void set(Quat q){
w = q.w;
x = q.x;
y = q.y;
z = q.z;
}
static Quat mul(Quat q1, Quat q2){
Quat res = new Quat();
res.w = q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z;
res.x = q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y;
res.y = q1.w * q2.y + q1.y * q2.w + q1.z * q2.x - q1.x * q2.z;
res.z = q1.w * q2.z + q1.z * q2.w + q1.x * q2.y - q1.y * q2.x;
return res;
}
float[] getValue(){
// transforming this quat into an angle and an axis vector...
float[] res = new float[4];
float sa = (float) Math.sqrt(1.0f - w * w);
if (sa < EPSILON){
sa = 1.0f;
}
res[0] = (float) Math.acos(w) * 2.0f;
res[1] = x / sa;
res[2] = y / sa;
res[3] = z / sa;
return res;
}
}
main
Arcball arcball;
//framecount
int fcount, lastm;
float frate;
int fint = 3;
boolean[] keys = new boolean[4];
final int w = 0;
final int s = 1;
final int a = 2;
final int d = 3;
void setup() {
size(900, 700, P3D);
frameRate(60);
noStroke();
arcball = new Arcball(width/2, height/2+100, 360);
}
void draw() {
lights();
background(255,160,122);
if(keys[w]) { arcball.rollforward(); }
if(keys[a]) { arcball.rollleft(); }
if(keys[s]) { arcball.rolldown(); }
if(keys[d]) { arcball.rollright(); }
ambient(80);
lights();
translate(width/2, height/2-100, 0);
box(50);
translate(0, 200, 0);
arcball.run();
box(50);
}
void keyPressed() {
switch(key) {
case 97:
keys[a] = true;
break;
case 100:
keys[d] = true;
break;
case 115:
keys[s] = true;
break;
case 119:
keys[w] = true;
break;
}
}
void keyReleased() {
switch(key) {
case 97:
keys[a] = false;
break;
case 100:
keys[d] = false;
break;
case 115:
keys[s] = false;
break;
case 119:
keys[w] = false;
break;
}
}
will add support for multiple keys at once later with an edit.... stay tuned
Hi
I have a program where you drag and drop circles on a scene using JavaFX. I don't want circles to collide to each other so I added a collision algorithm to check that, which now works. What puzzles me is what I want to do afterwards.
If two circles overlap I want to make a vector between the middle of the two and transform the moved circle in the direction of the vector until they no longer overlap.
for (Stone stn:getCurrentScenario().getStones()) {
if (stn.circle == circle) continue;
double x1 = stn.circle.getTranslateX();
double y1 = stn.circle.getTranslateY();
double r1 = stn.circle.getRadius()+stn.circle.getStrokeWidth();
double x2 = circle.getTranslateX();
double y2 = circle.getTranslateY();
double r2 = circle.getRadius();
double distSq = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
double radSumSq = (r1 + r2) * (r1 + r2);
if (!(distSq != radSumSq && distSq > radSumSq)) {
System.out.println("Collision.");
// Transform "circle".
}
}
I ended up skipping the vector idea and went by angle instead. Going to keep the title if someone else runs into a similar issue:
double newX = circle.getTranslateX();
double newY = circle.getTranslateY();
for (Stone stn:getCurrentScenario().getStones()) {
if (stn.circle == circle) continue;
double x1 = stn.circle.getTranslateX();
double y1 = stn.circle.getTranslateY();
double r1 = stn.circle.getRadius()+stn.circle.getStrokeWidth();
double x2 = newX;
double y2 = newY;
double r2 = circle.getRadius();
double distSq = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
double radSumSq = (r1 + r2) * (r1 + r2);
if (!(distSq != radSumSq && distSq > radSumSq)) {
double angle = Math.atan2(x1-x2,y1-y2);
newX = x1 - Math.sin(angle) * (circle.getRadius() + circle.getStrokeWidth() + stn.circle.getRadius() + .01);
newY = y1 - Math.cos(angle) * (circle.getRadius() + circle.getStrokeWidth() + stn.circle.getRadius() + .01);
}
}
for (Stone stn:getCurrentScenario().getStones()) {
if (stn.circle == circle) continue;
double x1 = stn.circle.getTranslateX();
double y1 = stn.circle.getTranslateY();
double r1 = stn.circle.getRadius()+stn.circle.getStrokeWidth();
double x2 = newX;
double y2 = newY;
double r2 = circle.getRadius();
double distSq = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
double radSumSq = (r1 + r2) * (r1 + r2);
if (!(distSq != radSumSq && distSq > radSumSq)) {
newX = oldX;
newY = oldY;
break;
}
}
circle.setTranslateX(newX);
circle.setTranslateY(newY);
I made that piece of code just to make sure that it works as intended. Going to improve it now.
My program contains main shapes i.e square, rect, circle they work good ( for x2,y2 in those shapes I used absolute values e.g square( x, y, 5, 5) ), but when working with triangle shape,
Triangles in my program glitches.
below is the code of my program modules,
if (vehicleStyle.getVehicleShape().equals(VehicleShape.TRIANGLE)) {
processingVisualizer
.fill(vehicleStyle.getColor().red,
vehicleStyle.getColor().green,
vehicleStyle.getColor().blue);
processingVisualizer.strokeWeight(1 * vehicleSize);
//System.out.println(x + "-" + y);
//## to place face toward movement direction
/*
* -----<|----
* | |
* \/ /\
* | |
* -----|>----
*/
float x2, y2, x3, y3;
if (x == 100) {
System.out.println( "x==100");
x2 = x - 5;
y2 = y + 5;
x3 = x + 5;
y3 = y + 5;
processingVisualizer.triangle(x, y, x2, y2, x3, y3);
} else if (x == 20) {
System.out.println( "x==20");
x2 = x - 2;
y2 = y - 2;
x3 = x + 2;
y3 = y - 2;
processingVisualizer.triangle(x, y, x2, y2, x3, y3);
} else if (y == 100) {
System.out.println( "y ==100");
x2 = x - 2;
y2 = y - 2;
x3 = x - 2;
y3 = y + 2;
processingVisualizer.triangle(x, y, x2, y2, x3, y3);
} else if (y == 20) {
System.out.println( "y ==20");
x2 = x+5;//x - 2;
y2 = y-5;
x3 = x+5 ;//- 2;
y3 = y+5;
processingVisualizer.triangle(x, y, x2, y2, x3, y3);
}
}
processingVisualizer.strokeWeight(1);
}
Can't test your code, but my assumption is the "glitch" happens because you are rendering a triangle only when your 4 conditions are met. You should update the triangle's corner positions based on your conditions if you like, but render the triangle all time, even when the positions are out of date:
if (vehicleStyle.getVehicleShape().equals(VehicleShape.TRIANGLE)) {
processingVisualizer
.fill(vehicleStyle.getColor().red,
vehicleStyle.getColor().green,
vehicleStyle.getColor().blue);
processingVisualizer.strokeWeight(1 * vehicleSize);
//System.out.println(x + "-" + y);
//## to place face toward movement direction
/*
* -----<|----
* | |
* \/ /\
* | |
* -----|>----
*/
float x2, y2, x3, y3;
if (x == 100) {
System.out.println( "x==100");
x2 = x - 5;
y2 = y + 5;
x3 = x + 5;
y3 = y + 5;
} else if (x == 20) {
System.out.println( "x==20");
x2 = x - 2;
y2 = y - 2;
x3 = x + 2;
y3 = y - 2;
} else if (y == 100) {
System.out.println( "y ==100");
x2 = x - 2;
y2 = y - 2;
x3 = x - 2;
y3 = y + 2;
} else if (y == 20) {
System.out.println( "y ==20");
x2 = x+5;//x - 2;
y2 = y-5;
x3 = x+5 ;//- 2;
y3 = y+5;
}
processingVisualizer.triangle(x, y, x2, y2, x3, y3);
}
processingVisualizer.strokeWeight(1);
}
Also, you can easily compute the direction of motion, if you store the previous position, using the arc tangent function (atan2()):
float angle = atan2(currentY-previousY,currentX-previousX);
Here's a quick example:
float cx,cy,px,py;//current x,y, previous x,y
float len = 15;
void setup(){
size(200,200);
background(255);
}
void draw(){
//update position - chase mouse with a bit of easing
cx -= (cx - mouseX) * .035;
cy -= (cy - mouseY) * .035;
//find direction of movement based on the current position
float angle = atan2(cy-py,cx-px);
//store previous position
px = cx;
py = cy;
//render
fill(255,10);noStroke();
rect(0,0,width,height);
fill(127,32);stroke(0);
pushMatrix();
translate(cx,cy);
pushMatrix();
rotate(angle);
triangle(len,0,-len,-len,-len,len);
line(0,0,len,0);
popMatrix();
popMatrix();
}