Slope between two points in X,Y,Z coordinate system - java

I took a course in Java at University 2 years ago, and now I have to create a program where I type in 2 sets of coordinates, and the program will create a 3-D graph of a line between the two points, as well as give the slope and angle between the two points. I've been trying to get familiar with the Java syntax, but I have to complete the program by tomorrow so I figured I would ask for help. I've put together code, but it isn't in Java's syntax (most of it isn't anyways) and I need help converting it to code that will work. I'm using double for my variables because the points the user enters can be decimals. The only coordinates the user will input are x, and y for both points, the z coordinates are set at z1 = 0 and z2 = 1. The way I have put the variables together, it assumes the z coordinate extends out of the screen, and the y coordinate plane extends vertically.
Again, I'm familiar with general coding terms, but as I've looked around on the internet i see things like import java.util.* and that stuff doesn't make sense to me as to how it owuld apply to my program.
Any help is appreciated!
P.S. if you want me to add comments as to what certain things mean, let me know. i.e. create.cube is a syntax I made up, but I want the computer to create a window that will show a cube with the coordinates I have set.
package slope;
public class Slope1 {
double xvar;
double yvar;
double zvar;
xvar x1 = new xvar;
xvar x2 = new xvar;
yvar y1 = new yvar;
yvar y2 = new yvar;
zvar z1 = new zvar;
zvar z2 = new zvar;
public static void main(String[]args){
z1 = 0;
z2 = 1;
get.x1 from user
if(x1>9 or x1<-9){
System.out.println("Please choose values within range")
}
get.x2 from user
if(x2>9 or x2<-9){
System.out.println("Please choose values within range")
}
get.y1 from user
if(y1>12 or y2<-12){
System.out.println("Please choose values within range")
}
get.y2 from user
if(y1>12 or y2<-12){
System.out.println("Please choose values within range")
}
slope1 = (y2-y1)/(x2-x1);
angle1 = arctan(slope1);
distance1 = (y2-y1)/sin(angle1);
slopeFinal = 1/distance1;
angleFinal = arctan(slopeFinal);
System.out.println("Your Slope is " + slopeFinal);
System.out.println("Angle of entry is " + angleFinal);
}
public static void main(String[]args){
create.cube;
xlength cube = -9 to 9;
ylength cube = -12 to 12;
zlenght cube = 0 to 12
cube x origin at x=0;
cube y origin at y=0;
cube z origin at z=0;
draw line from (x1,y1,z1) to (x2,y2,z2) in cube;
}
}

Your code doesn't make sense at all and has many syntax errors.
create.cube;
xlength cube = -9 to 9;
ylength cube = -12 to 12;
zlenght cube = 0 to 12
cube x origin at x=0;
cube y origin at y=0;
cube z origin at z=0;
None of the above are valid statements in java.
You might wanna study java once again and look up gui programming with java as well. below is a link to get you started.
https://en.wikibooks.org/wiki/Java_Programming

Related

Trying to draw polygons with JFrame

I want to code a program in java that utilises loops and JFrame to create various polygons around one another.
ie. Triangle, then Square, then Pentagon etc...
Refrence image of example
super.paintComponent(g);
int y = 0;
int z = 0;
g2D.setPaint(Color.CYAN);
Polygon p = new Polygon();
for (int x = 4; x < 10; x++) {
y = y + 50;
z = z + 100;
System.out.println("y = "+y);
System.out.println("z = " + z);
for (int i = 0; i < 10; i++) {
p.addPoint((int) (z + y * Math.cos(i * 2 * Math.PI / x)),
(int) (z + y * Math.sin(i * 2 * Math.PI / x)));
}
g2D.drawPolygon(p);
}
}
Output of Code
Any help would be much appreciated.
Oracle has a helpful tutorial, Creating a GUI With Swing. Skip the Learning Swing with the NetBeans IDE section. Pay close attention to the Performing Custom Painting section.
This is a picture of what the OP is supposed to draw.
The only regular polygon in the picture is the square. At least, I think it's a square.
The triangle is an isosceles triangle.
I'm not sure how you would define the pentagon. The five sides are not equal in length. The side two segments are shorter than the bottom segment. The top two segments appear to be longer than the bottom segment.
You can't use the center point and angle of rotation math to create the polygons. The triangle is not an equilateral triangle.
You have to create this by calculating line segments. I'm assuming that the three polygons share the same base. Calculate one line segment at a time and test your code. You're going to run hundreds of tests before you're done.
I'd start by calculating the square first. A square is made up of four equal length line segments. To start, I'd take 1/2 of the width of the drawing area to be the length of the line segment. The first two X values are at the 1/4 and 3/4 points. The Y value can be 20 pixels off the bottom.
Now that you've drawn one line segment, calculate the line segments for the square. Draw the square.
Find the midpoint of the top square line segment. calculate the triangle line segments. Draw the triangle.
For the pentagon, the side line segments are shorter than the line segments of the square. Each angle of a regular pentagon is 108 degrees from the previous line segment. This polygon has slightly different angles at each point.
You'll have to experiment with the pentagon line segment lengths until the top two segments just intersect the square line segments. You could probably do the math, but I suspect it would be easier to just keep guessing until you get an acceptable drawing.
Edited to add:
I created the following GUI.
Calculating the pentagon line segments took the most time.
The side line segments are 85% of the line length of the bottom line segment. I used a 105 degree angle to calculate the end points of the side line segments.
I used a slope formula to calculate the y point of the top line segments. I'd already calculated the start point and the intersect point to draw the pentagon side line segments and the square, respectively. This calculation took most of my debugging time.
Edited to add:
I don't want to just give you the complete code. Part of learning is struggling with the code and learning how to solve problems as they come up. As I said, you should be writing a little bit of code at a time and testing each little bit of code to see what it does.
Here are two methods I wrote to calculate the four additional pentagon line segments. The Point class is java.awt.Point.
private Point calculateSideSegment(Point start, int radius, int angle) {
double theta = Math.toRadians(angle);
int x = (int) Math.round(Math.cos(theta) * radius) + start.x;
int y = (int) Math.round(Math.sin(theta) * radius) + start.y;
return new Point(x, y);
}
private int calculateTopSegment(Point start, Point intersect, int x) {
int yDiff = start.y - intersect.y;
int xDiff1 = start.x - intersect.x;
int xDiff2 = start.x - x;
double slope = (double) yDiff / xDiff1;
double y = Math.round(slope * xDiff2);
return start.y - (int) y;
}

How to fully make 2d to 3d?

I'm using the method of dividing the x and y coordinates by the z value, then rendering it just like you would a 2D game/thing to create 3D looking thing. The problem is when the z value is less then 0 it flips the quadrants for the coordinate and looks very weird. At the moment there is only movement if someone could help me fix the negative z value thing and show me how to rotate. I'm not using and matrices only vectors that take in x,y and z for the maths if that helps. I'm making this using Java with no extra libraries.
Thanks for the help.
I used the perspective matrix and multiplied it by my vector but it didn't work here is my code there might be something wrong with it. I just turned the vector into a 1 by 3 matrix and then did this.
public Matrix multiply(Matrix matrix)
{
Matrix result = new Matrix(getWidth(),getHeight());
for(int y = 0; y < getHeight()-1; y++)
{
for(int x = 0; x < getWidth()-1; x++)
{
float sum = 0.0f;
for(int e = 0; e < this.getWidth()-1; e++)
{
sum += this.matrix[e + y * getWidth()] * matrix.matrix[x + e * matrix.getWidth()];
}
result.matrix[x + y * getWidth()] = sum;
}
}
return result;
}
Just guessing here, but it sounds like you are trying to do a projection transform: You are modeling 3D objects (things with X, Y, and Z coordinates) and you want to project them onto a 2D window (i.e., the screen).
The meaning of Z in the naive projection transform is the distance between the point and a plane parallel to the screen, that passes through your eyeball. If you have points with -Z, those represent points that are behind your head.
Sounds like you need to translate the Z coordinates so that Z=0 is the plane of the screen, or a plane parallel to and behind the screen. (In other words, Add a constant to all of your Zs, so that none of them is negative.)
http://en.wikipedia.org/wiki/3D_projection

Finding the change needed in location to move around the circumference of a circle#2

I asked about this yesterday as well and was told that I needed to be using radians. I had assumed that was the answer but there does appear to be another problem with the code below. I am trying to write a method which will allow my Gladiators to rotate a central point between the two, to circle each other so to speak. Below is my code. Gladiator variable target is of Gladiator type and is set to the second party in the rotation. center[0] is the x location, center[1] is y.
public void rotate(Gladiator a, int angle) {
double x1;
double y1;
double x2;
double y2;
double r;
double midx;
double midy;
int currentAngle;
r = getDistance(a,a.target)/2;
midx = (a.center[0]-a.target.center[0])/2;
midy = (a.center[1]-a.target.center[1])/2;
currentAngle = (int)Math.toDegrees(Math.atan2(a.center[1] - midy, a.center[0] - midx));
x1 = Math.cos(Math.toRadians(currentAngle+angle)) * r;
y1 = Math.sin(Math.toRadians(currentAngle+angle)) * r;
x2 = Math.cos(Math.toRadians(currentAngle+angle)) * -r;
y2 = Math.sin(Math.toRadians(currentAngle+angle)) * -r;
a.move((int)x1,(int)y1);
a.target.move((int)x2,(int)y2);
}
Anyone see anything wrong with this? At the moment they end up meeting towards what I would think would be the middle of my circle, waaay closer than they were. Any thoughts?
Edit: Also, I am currently running this twice... once for each Gladiator involved. I can do that and just have them rotate half the desired amount each time, but it would be better if I could rotate them as a whole then disinclude the second party from the Gladiator list I am iterating through. What would be the most simple implementation of this?
Edit2: I think part of my problem was that I wasn't calling Math.toDegrees on my atan2 equation. I noticed it wasn't getting any new angle value other than 0, now it is. Still, there is something wrong. They rotate from horizontal to vertical but are moving much further from each other on each rotation and once they get to the vertical alignment they end up rotating the other direction just a few degrees (rather than 45, my current input) and then do get much closer together like before.
Edit3: Note that the move method's parameters are the change needed, not the actual coordinates.
I see you are using int a lot, be very careful since you may get stuck depending on angle.
I did a quick rewrite to simplify your repetition and use the radian logic that was recommended. (Untested).
I also converted your locations to double to avoid odd integer arithmetic problems. (Your midx/midy calculations were in int math)
After finishing I realized you were rotating around (0,0) rather than the midpoint, and your mid variables were confusingly named.
//I would do double inline with the initialization, but left here in case you had another reason
double x1,y1, x2,y2, r, midx,midy, newAngle;
x1 = a.center[0];
y1 = a.center[1];
x2 = a.target.center[0];
y1 = a.target.center[1];
r = getDistance(a, a.target)/2;
midx = x1 + (x2 - x1)/2;
midy = y1 + (y2 - y1)/2;
newAngle = Math.toRadians(angle) +
Math.atan2(midy, midx);
x1 = Math.cos(newAngle) * r + midx;
y1 = Math.sin(newAngle) * r + midy;
x2 = Math.cos(newAngle) * -r + midx;
y2 = Math.sin(newAngle) * -r + midy;
a.move((int)x1,(int)y1);
a.target.move((int)x2,(int)y2);

Distance between multiple coordinates

I am completely lost on how to sort the coordinates into an array, and find the distance between them. This is the question:
Create a new class called “Circle” that can be used to create customized circle objects. Your class should include the following – be sure to comment your class appropriately:
double radius,
double xPosition,
double yPosition, and
A method that computes the distance from the xPosition and yPosition of one circle to the xPosition and yPosition of another circle. Use the standard distance formula to compute this value. You only need to compute the distance from center point to center point for the purposes of this method. Here’s a method header to get you started:
public double distanceFrom(Circle test)
Create a new class called “Assignment06b”. Do the following in this class:
Prompt the user to enter in a number of circles (i.e. How many circles do you want to create?)
Next, ask the user to enter in the radius, xPosition and yPosition for each circle. Store their input in an array of Circles of the appropriate size.
Finally, Iterate through your array and display distance information for each circle. Ensure that you do not calculate the distance from a given circle back to itself (i.e. no need to compute distance between circle #1 and circle #1) — Here’s a sample running of your program.
Here's what I have so far:
import java.util.Scanner;
public class Assignment06b
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
System.out.print("How many circles do you want to create?:");
int amount = input.nextInt();
int[] arrayX = new int [amount];
int[] arrayY = new int [amount];
int counter = 0;
for (counter = 0; counter < amount; counter++)
{
System.out.println("Enter info for Circle #" + (counter + 1));
System.out.print("Radius: ");
double width = input.nextDouble();
System.out.print("X Position: ");
arrayX[counter] = input.nextInt();
System.out.print("Y Position:");
arrayY[counter] = input.nextInt();
}
}
class Circle
{
double radius;
double xPosition;
double yPosition;
Circle(double radius, double xPosition, double yPosition)
{
}
public double distanceFrom(Circle test)
{
double equation = (xPosition-xPosition)*(xPosition-xPosition) + (yPosition-yPosition)*(yPosition-yPosition);
double answer = Math.pow(equation, 0.5);
return answer;
}
}
}
You are tip toeing around object orientation here, change things around so you have an array of circles instead of an array of ints:
Circle[] arrayCircles = new Circle [amount];
Also you aren't setting any values in your circle class, you probably want to fix that:
Circle(double radius, double xPosition, double yPosition)
{
this.radius = radius;
this.xPosition = xPosition;
this.yPosition = yPosition;
}
Then you can add circles to your collection like this:
arrayCirles[0] = new Circle(myRadius, myXPosition, myYPosition);
and call your distanceFrom method call like so:
//Obviously do this in a loop of some kind and make sure they exist first
arrayCircles[0].distanceFrom(arrayCircles[1]);
Hopefully the rest you can figure out yourself
(Also take another look at your distanceFrom method, you want to compare the circle you are passed as a parameter, not to yourself)
I'm currently working in a CAD software and I needed to find the distance between circles (holes) in a square grid/array and I found that the distance between circles (edge to edge) is given by
(L-N*D)/(N-1)
Where:
L is the distance of the array from edge to edge (not to the centre point of the end circle but to the edge of end circles)
N is the number of circles
D is the diameter of the circles
if you measure L from centre point to centre point
(L+D-N*D)/(N-1)
If you're looking to find the distance between centre point to centre point I'm sure you can derive it
Bit late but hopefully this helps someone else!

Bresenham 3d Ellipsoid problems

I'm making an ellipsoid out of voxels, and I have an implementation, but it's not working correctly, for the past few hours I've been trying things with no success.
Here's how it works:
It draws 2D ellipses down the Z axis using the Bresenham circle algorithm
It calculates the coordinates of a circle going forward and one going side to side
It uses those coordinates as radii for X and Y
Here's what works:
Spheres are perfect
Ellipsoids are perfect when
z > x and z > y
x == y
Here's what doesn't:
Ellipsoids when x != y
Example when y > x http://postimage.org/image/gslvykrgd/
The same thing happens when x > y only flipped
I'm guessing its because I'm drawing the slices from center to front every time, but I don't know. Below is my implementation, it's a mess. I quickly cleaned it up a bit so it's understandable to some degree. Also I'm saving optimisations for later, I just want it working now.
I won't show my implementation of the circle algorithm itself, because I KNOW that it works and it would just make this question longer. So I'll explain the two functions for it instead.
private List<Integer> getSlice(int rx, int ry) gets the raw result from a run of the Bresenham circle algorithm, no symmetry needed. It returns the result as a list of the x, y results in that order.
public void generateEllipse(int z, int cx, int cy, int cz, int rx, int ry) generates an ellipse with the given information and plots down the coordinates using symmetry, these will be rendered on the screen.
ArrayList<Integer> s = getSlice(rz, rx);
ArrayList<Integer> s2 = getSlice(rz, ry);
int cap = Math.max(s2.size(), s.size());
while (s.size() > 1)
{
int x = 0;
int z = 0;
int z2 = 0;
int y2 = 0;
int i = cap - 2;
if (s.size() > i)
{
z = s.get(i);
x = s.get(i + 1);
s.remove(i + 1);
s.remove(i);
}
if (s2.size() > i)
{
z2 = s2.get(i);
y2 = s2.get(i + 1);
s2.remove(i + 1);
s2.remove(i);
}
if (x != 0 && y2 != 0)
generateEllipse(z, cx, cy, cz, x, y2);
cap = Math.max(s2.size(), s.size());
I asked a similar question a week or two back (yeah I've been having problems for that long :() and got an answer, I implemented it and it worked, but I wasn't satisfied, I want to avoid floating point numbers all together. See 3D Ellipsoid out of discrete units.
With that I was having problems with rounding off the numbers and getting uneven slices, so spheres were impossible. Ironically, now spheres are the only thing possible (other than front to back ellipses).
EDIT:
I got x > y working by adding
else if (y2 < x && ry - y2 != 0)
generateEllipse(z, cx, cy, cz, x, ry - y2);
and || r - y2 == 0 to the first test at the bottom.
I'm not too sure why that worked, I'm figuring that out now. But I'm still having problems with y > x. Anyone?
EDIT2:
Now that I look at it, it's different than the y = x ellipsoid, back to the drawing board.
EDIT3:
Last night I was thinking about this and I think I've figured it out, this isn't an answer to my own question, but I guess pointing out what I'm seeing to be wrong. I'm testing for the first list and drawing coordinates decrementally from the size of the largest list.
That's badness because the two lists aren't guaranteed equal lengths, that's a failure on my part for trying to rush an algorithm.
In the picture, you can't see, but the little ellipse is actually a few blocks away from the big ellipse. This is caused when from ellipses not being drawn, which is caused by lists not having data. The actual little ellipse big ellipse is caused because the algorithm draws two octants, both of which are stored into the list from getSlice(...).
So how can I fix this problem? I haven't implemented anything yet and probably won't for a while (it's early) but this is what my brain cranked out. Again, this is not an answer to the question, just thoughts.
I iterate for while(!s.isEmpty()) and define two new values outside the loop: incX = s.size and incY = s1.size I test to see if their z values match, if not, then I correct it. I'm thinking I'll get the values, test the largest list and if they don't match then decrement the inc value of the smallest list by two and get the old values.
I test for !s.isEmpty() because the two lists will be empty at the same time. Also drawing ellipses, I'll use whichever one z value, because, again, they both should be equal.
If that's wrong, then I guess I have this document I found to go through: http://www.cs.sunysb.edu/vislab/wordpress/pdf/398.pdf.
Thank you for anyone who viewed this (even though I didn't get any replies :(), I'm setting this answer because the problem is solved, the code is as follows:
ArrayList<Integer> s = getSlice(rz, rx);
ArrayList<Integer> s2 = getSlice(rz, ry);
boolean yMax = Math.max(s2.size(), s.size()) == s2.size();
int decX = s.size() - 1;
int decY = s2.size() - 1;
boolean done = false;
while (!done)
{
int x = 0;
int z = 0;
int z2 = 0;
int y = 0;
y = s2.get(decY--);
z2 = s2.get(decY--);
x = s.get(decX--);
z = s.get(decX--);
if (z != z2)
{
if (yMax)
{
decX += 2;
x = s.get(decX);
s2.remove(decY + 2);
s2.remove(decY + 1);
}
else
{
decY += 2;
y = s2.get(decY);
s.remove(decX + 2);
s.remove(decX + 1);
}
z = z < z2 ? z : z2;
}
else
{
s.remove(decX + 2);
s.remove(decX + 1);
s2.remove(decY + 2);
s2.remove(decY + 1);
}
if (y != 0 && x != 0)
generateEllipse(z, cx, cy, cz, x, y);
done = yMax ? s2.isEmpty() : s.isEmpty();
}
All that needs to be done now is optimisation. I'm still going to read that paper, it covers other topics that are interesting and useful for my program :).
The issue was that I was not accounting for the different sizes of each list, if a curve is less steep than the other it will have more coordinates. Z will always be the same when rx == ry. This allowed me to draw spheres and forward to back ellipsoids.
When they are not the same the z will change because the curve will be faster / slower. When this happened while I was testing for the first list it would ignore those because iteration would stop before it got to them.
The big ellipse, little ellipse was caused because they were drawn backwards, so the outer octant was drawn first which happens to have less total values.
In the near future I will put up a much more detailed answer and a much more elegant implementation. I'm just putting up this answer to let any passersby know that the problem is resolved. I want no one to ever go through the frustration I did trying to figure this whole thing out! It's amazing how the most difficult problems are caused by the silliest things.

Categories

Resources