The purpose of the method is to take in a Point (c), then move the current centroid (x,y) to the new coordinated provided. This is done through finding the difference of the two and then translating the point to the new coordinate. However, I do not know how to set the new centroid value since I am setting the methods as voids.... Any ideas?
Sorry for all of the code, tried to put as little as possible. Translate takes the point(x,y) and adds the values given (dx,dy).
private Point centroid;
Triangle(Point a, Point b, Point c) {
this.a = a;
this.b = b;
this.c = c;
triPoints = new Point[] { a, b, c };
}
public Point getCentroid() {
Point centroid;
double x = 0.0;
double y = 0.0;
x = (a.getX() + b.getX() + c.getX()) / 3;
y = (a.getY() + b.getY() + c.getY()) / 3;
centroid = new Point(x, y);
return centroid;
}
public void move(double dx, double dy) {
centroid = getCentroid();
System.out.println(centroid.getX() + " "+ centroid.getY());
centroid = centroid.translate(dx, dy);
Point newCentroid = new Point(centroid.getX(),centroid.getY());
System.out.println(newCentroid.getX() + " "+ newCentroid.getY());
if(getCentroid().equals(newCentroid)){
}else{
}
for (int index = 0; index < triPoints.length - 1; index++) {
triPoints[index].translate(dx, dy);
}
}
public void move(Point c) {
double firstx = 0.0;
double firsty = 0.0;
Point f = getCentroid();
System.out.println(f.getX()+ " "+ f.getY() + " "+ c.getX()+ " "+ c.getY());
if (f.getX() >= c.getX()) {
firstx = c.getX() - f.getX();}
else{
firstx = Math.abs(f.getX() - c.getX());
}
if (f.getY()>= c.getY()){
firsty = c.getY() - f.getY();
}
else {
firsty = Math.abs(f.getY() -c.getY());
}
move(firstx, firsty);
//System.out.println(centroid.getX() + " " + centroid.getY());
}
I am assuming you are using java.awt.Point?
If so, centroid.translate(dx, dy) is a void method: no value is actually returned, so
centroid =centroid.translate(dx, dy)
does not actually do anything.
Since you are just wanting a new centroid, try doing
centroid = getCentroid();
System.out.println(centroid.getX() + " "+ centroid.getY());
Point newCentroid = new Point(centroid.getX() + dx,centroid.getY() + dy);
System.out.println(newCentroid.getX() + " "+ newCentroid.getY());
There is no need to do the translate if all you want to do once you translate is make a new centroid.
Also, neither the translate function nor the constructor take a double (which makes sense if you are on a standard x,y graph), so you can make dx and dy int.
Related
Seq is a method which for given line: line's point a and slope b returns perimeter of circular segment. I used the equation of circle and line and solved it for x, and then I easily get two points. But instead of (3.5,1.9) approximately I get (6.528,0.0832000000000006)..
public class Circle {
Point center;
double r;
public double seq(Point a, double b) {
double n = -b*a.getX() + a.getY();
System.out.println("n: "+n);
if (r*r*(b*b+1)-Math.pow(b*center.getX()-center.getY()+n, 2) > 0) {
double temp = (1+b*b);
System.out.println("coeficient x^2: "+temp);
double temp1 = 2*((-1)*center.getX()+b*n-b*center.getY());
System.out.println("coeficient x: "+ temp);
double free_term = center.getX()*center.getX() + n*n -2*n*center.getY() + center.getY()*center.getY() - r*r;
System.out.println("free term: "+free_term);
double D = Math.sqrt(temp1*temp1-4*temp*free_term);
System.out.println(temp1*temp1-4*temp*free_term);
double x1 = ((-1)*temp1+Math.sqrt(temp1*temp1-4*temp*free_term))/2*temp;
double x2 = ((-1)*temp1-Math.sqrt(temp1*temp1-4*temp*free_term))/2*temp;
double y1 = b*x1 - b*a.getX() + a.getY();
double y2 = b*x2 - b*a.getX() + a.getY();
System.out.println("("+x1+","+y1+")"+", ("+x2+","+y2+")");
Point A = new Point(x1,y1);
Point B = new Point(x2,y2);
double d = A.dist(B);
System.out.println("d: "+d);
double angle = Math.acos((2*r*r-d*d)/2*r*r);
System.out.println("angle "+ alfa);
double l = r*Math.PI*angle/Math.toRadians(180);
return l+d;
} else return 0;
}
}
Main:
Circle k = new Circle();
Point c = new Point(0,0);
k.center = c;
k.r = 4;
Point a = new Point(0,4);
System.out.println(k.seq(a, -3.0/5.0));
Console:
n: 4.0
coeficient x^2: 1.3599999999999999
coeficient x: -4.8
free term: 0.0
23.04
(6.528,0.0832000000000006), (0.0,4.0)
d: 7.612890793910023
angleNaN
NaN
Your problem is in the implementation of the quadratic formula. You might think that A/2*B means A/(2*B) but in reality it's (A/2)*B. So add the parentheses in around the divisor:
double x1 = ((-1)*temp1+Math.sqrt(temp1*temp1-4*temp*free_term))/(2*temp);
double x2 = ((-1)*temp1-Math.sqrt(temp1*temp1-4*temp*free_term))/(2*temp);
In an STL format this is what my current landscape looks like. And this is what the landscape is suppossed to look like. I think I know what the problem is, but I have no clue how to solve it.
I think I need to set the Z coordinate relative to other points around it so the whole landscape's Z coordinate isn't between 0 and 1 but they rather "add up".
Don't want a solution, just a hint in the right direction.
import java.io.*;
import java.util.Random;
class Point3D {
double x, y, z;
Point3D(double dx, double dy, double dz) {
x = dx;
y = dy;
z = dz;
}
Point3D middlePoint(Point3D p) {
Point3D m = new Point3D(0.0, 0.0, 0.0);
m.x = (this.x + p.x) / 2.0;
m.y = (this.y + p.y) / 2.0;
m.z = (this.z + p.z) / 2.0;
return m;
}
}
public class Aufgabe3 {
public static void recursion(Point3D p1, Point3D p2, Point3D p3, int n) {
if (n > 0) {
if (n == 1) {
System.out.println(" facet normal 0.0 0.0 0.0");
System.out.println(" outer loop");
System.out.println(" vertex " + p1.x + " " + p1.y + " " + p1.z);
System.out.println(" vertex " + p2.x + " " + p2.y + " " + p2.z);
System.out.println(" vertex " + p3.x + " " + p3.y + " " + p3.z);
System.out.println(" endloop");
System.out.println(" endfacet");
}
Random r = new Random();
Point3D a = p1.middlePoint(p2);
Point3D b = p3.middlePoint(p1);
Point3D c = p2.middlePoint(p3);
long seedA = (long) ((p1.x + p1.y + p1.z + p2.x + p2.y + p2.z) * 1000000);
r.setSeed(seedA);
a.z = r.nextDouble() / 10;
long seedB = (long) ((p3.x + p3.y + p3.z + p1.x + p1.y + p1.z) * 1000000);
r.setSeed(seedB);
b.z = r.nextDouble() / 10;
long seedC = (long) ((p2.x + p2.y + p2.z + p3.x + p3.y + p3.z) * 1000000);
r.setSeed(seedC);
c.z = r.nextDouble() / 10;
recursion(p1, a, b, n-1);
recursion(a, p2, c, n-1);
recursion(b, c, p3, n-1);
recursion(a, b, c, n-1);
}
}
public static void main(String args[]) throws FileNotFoundException {
int n;
try {
n = Integer.parseInt(args[0]);
}
catch (Exception e) {
n = 7;
}
System.out.println("Aufgabe 3: Landschaftsgenerator");
System.out.println("n = " + n);
Random r = new Random();
Point3D p1 = new Point3D(0.8, -1.2, 0.0);
Point3D p2 = new Point3D(1.0, 1.3, 0.0);
Point3D p3 = new Point3D(-1.0, 0.0, 0.0);
System.setOut(new PrintStream(new FileOutputStream("Aufgabe3.stl")));
System.out.println("solid Aufgabe3");
recursion(p1, p2, p3, n);
System.out.println("endsolid");
}
}
The problem is the frequency distribution of the displacements you're adding. Displacements to a fractal landscape have to follow a 1/(f^b) distribution, otherwise you get random noise.
In this case, no matter what the scale of subdivision, you're adding the same vertical displacement, which is going to result in a landscape dominated by the highest frequency. Formally, a fractal surface is one that has a 'fractional' or 'fractal' geometric dimension, higher than the topological dimension of the surface, but lower than that of the embedding space. For instance, for a 2D surface being displaced in the 3rd dimension, the fractal dimension should be between 2 and 3.
For subdivision and displacement, the fractal dimension is related to beta as follows:
Dim = (7 - b)/2
With fractal behaviour therefore occurring between b = 1 and b = 3, and the random displacements follow this profile:
displacement = k * rand / (f^b)
This means that if you divide your triangle in half each time, you have to at least halve the displacement, or you'll end up with a noise surface rather than a fractal one. The best choice for a landscape is typically somewhere around b = 2.
Reference: https://fractal-landscapes.co.uk/maths.html
I am currently working on a 3D-library including quaternions. As every expert, I coded my methods based on what I found on Wikipedia and it doesn't work quite right.
This is the method for calculating the product between two quaternions:
public static Quaternion product(Quaternion a, Quaternion b) {
return a.clone().multiply(b);
}
And here is its implementation:
public Quaternion multiply(Quaternion q) {
float rx = q.getX(), ry = q.getY(), rz = q.getZ(), rw = q.getW();
this.w = w*rw - x*rx - y*ry - z*rz;
this.x = w*rx + x*rw + y*rz - z*ry;
this.y = w*ry - x*rz + y*rw + z*rx;
this.z = w*rz + x*ry - y*rx + z*rw;
return this;
}
And here is a small test that I wrote:
Quaternion a = Quaternion.create(1, 1, 1, Spatium.DEG_TO_RAD * 15);
Quaternion b = Quaternion.create(1, 1, 1, Spatium.DEG_TO_RAD * 15);
Quaternion c = Quaternion.product(a, b);
System.out.println(a + " * " + b + " = " + c);
Note that the create() method initializes quaternions with x, y, z, w.
Unfortunately, the tests yields results that don't make any sense despite my amazing skills of copying and pasting Wikipedia formulas:
(0.2617994 + 1.0i + 1.0j + 1.0k) * (0.2617994 + 1.0i + 1.0j + 1.0k) = (-2.931461 + -2.6696618i + 1.0j + -6.3393235k)
For comparison, Wolfram solves it correctly and returns -2.93146 + 0.523599i + 0.523599j + 0.523599k.
Here's the formulas I so skillfully copied from Wikipedia:
I don't really have anything to say other than please help me, Wikipedia couldn't.
I think you should store the current values of x, y, z and w in a temp variable before updating it with new values.
public Quaternion multiply(Quaternion q) {
float rx = q.getX(), ry = q.getY(), rz = q.getZ(), rw = q.getW();
float cx = x; // cx = current X
float cy = y;
float cz = z;
float cw = w;
this.w = cw*rw - cx*rx - cy*ry - cz*rz;
this.x = cw*rx + cx*rw + cy*rz - cz*ry;
this.y = cw*ry - cx*rz + cy*rw + cz*rx;
this.z = cw*rz + cx*ry - cy*rx + cz*rw;
return this;
}
In your code, when you use this.w = w*rw - x*rx - y*ry - z*rz;, you are overridind the current value of w, and the next 3 operations will be affected by this changes.
I have to create a class to calculate the distance between 2 given points for class. The instructor gave us the top half of the assignment with all the necessary code without modifying, the problem that im having is creating the class part. This is what i have so far...
class Point{
int x;
int y;
public Point(){
this.x = 0;
this.y = 0;
}
public Point(int x, int y){
this.x = x;
this.y = y;
}
public double distance(int x, int y) {
double d = Math.sqrt( Math.pow(x2-x1, 2) + Math.pow(y2-y1, 2) );
return distance;
}
}
the top half of the assignment looks like this:
import java.util.Scanner;
class Assignment4{
public static void main(String[] args){
// first and second points
Point first, second;
// try parsing points from command line args
if(args.length==4){
// new Point(int x, int y) creates a new Point located at position (x,y)
first = new Point(Integer.valueOf(args[0]), Integer.valueOf(args[1]));
second = new Point(Integer.valueOf(args[2]), Integer.valueOf(args[3]));
}
// if not specified as argument, get points from user
else{
Scanner input = new Scanner(System.in);
System.out.println("Enter first point: ");
first = new Point(input.nextInt(),input.nextInt());
System.out.println("Enter second point: ");
second = new Point(input.nextInt(),input.nextInt());
}
//calculate distance
//double d = Math.sqrt( Math.pow(x2-x1, 2) + Math.pow(y2-y1, 2) );
double d = first.distance(second.x, second.y);
System.out.println("Distance between " +
"(" + first.x + "," + first.y + ")" +
" and " +
"(" + second.x + "," + second.y + ")" +
" is " + d);
System.out.println();
}
}
When i try and compile the program, it says "cannot find symbol" referring to x2, x1, y2, y1, and distance.
Here :
class Point{
int x;
int y;
.....
.....
public double distance(int x, int y) {
double d = Math.sqrt( Math.pow(x2-x1, 2) + Math.pow(y2-y1, 2) ); //ERROR IN THIS LINE
return distance; //ERROR HERE TOO...(2)
}
}
There is no x1,x2,y1,y2 defined in the class or in the method parameter.
Swap it with the following line:
double d = Math.sqrt( Math.pow(this.x-x, 2) + Math.pow(this.y-y, 2) );
(2)
Error 2 Swap with this line:
return d;
I am calculating Geometric median of some (x,y) points in java. To calculate Geometric median, first i am calculating centroid of all the points, then this centroid is used to calculate Geometric median. My code works fine, but sometimes it goes to an infinite loop (i think.). The problem is with my while condition. This while condition should be change according to input points, but i don't know how. Below I am putting the complete code.
import java.util.ArrayList;
public class GeometricMedian {
private static ArrayList<Point> points = new ArrayList<Point>();
private class Point {
private double x;
private double y;
Point(double a, double b) {
x = a;
y = b;
}
}
public static void main(String[] args) {
GeometricMedian gm = new GeometricMedian();
gm.addPoints();
Point centroid = gm.getCentroid();
Point geoMedian = gm.getGeoMedian(centroid);
System.out.println("GeometricMedian= {" + (float) geoMedian.x + ", "
+ (float) geoMedian.y + "}");
}
public void addPoints() {
points.add(new Point(0, 1));
points.add(new Point(2, 5));
points.add(new Point(3, 1));
points.add(new Point(4, 0));
}
public Point getCentroid() {
double cx = 0.0D;
double cy = 0.0D;
for (int i = 0; i < points.size(); i++) {
Point pt = points.get(i);
cx += pt.x;
cy += pt.y;
}
return new Point(cx / points.size(), cy / points.size());
}
public Point getGeoMedian(Point start) {
double cx = 0;
double cy = 0;
double centroidx = start.x;
double centroidy = start.y;
do {
double totalWeight = 0;
for (int i = 0; i < points.size(); i++) {
Point pt = points.get(i);
double weight = 1 / distance(pt.x, pt.y, centroidx, centroidy);
cx += pt.x * weight;
cy += pt.y * weight;
totalWeight += weight;
}
cx /= totalWeight;
cy /= totalWeight;
} while (Math.abs(cx - centroidx) > 0.5
|| Math.abs(cy - centroidy) > 0.5);// Probably this condition
// needs to change
return new Point(cx, cy);
}
private static double distance(double x1, double y1, double x2, double y2) {
x1 -= x2;
y1 -= y2;
return Math.sqrt(x1 * x1 + y1 * y1);
}
}
Please help me to fix the bug, also if there exitis any better way to calculate Geometric median of some 2D points, write here. Thank you.
I don't see why you need two loops. You only need the loop over all the points. What is the reason for the other one, in your view?
One way to solve this is to iterate certain number of times. This similar to K-Means method where it either converges to a specific threshold or stops after a predefined number of iterations.