kopia lustrzana https://github.com/jameshball/osci-render
Implemented 3D code from ICHack project
rodzic
a55f57163c
commit
ca9382d272
|
@ -2,7 +2,7 @@ package audio;
|
|||
|
||||
import shapes.Ellipse;
|
||||
import shapes.Shapes;
|
||||
import shapes.Vector;
|
||||
import shapes.Vector2;
|
||||
|
||||
public class AudioClient {
|
||||
private static final int SAMPLE_RATE = 192000;
|
||||
|
@ -13,12 +13,20 @@ public class AudioClient {
|
|||
AudioPlayer player = new AudioPlayer();
|
||||
AudioPlayer.FORMAT = AudioPlayer.defaultFormat(SAMPLE_RATE);
|
||||
|
||||
AudioPlayer.addShapes(Shapes.generatePolygram(5, 3, 0.5, 60));
|
||||
// AudioPlayer.addShapes(Shapes.generatePolygram(5, 3, 0.5, 60));
|
||||
//AudioPlayer.addShapes(Shapes.generatePolygon(500, 0.5, 10));
|
||||
AudioPlayer.addShape(new Ellipse(0.5, 1));
|
||||
// AudioPlayer.addShape(new Ellipse(0.5, 1));
|
||||
|
||||
// AudioPlayer.setRotateSpeed(0.8);
|
||||
// AudioPlayer.setTranslation(2, new Vector(0.5, 0.5));
|
||||
|
||||
AudioPlayer.addShapes(Shapes.generatePolygon(4, new Vector2(0.25, 0.25)));
|
||||
AudioPlayer.addShapes(Shapes.generatePolygon(4, new Vector2(0.5, 0.5)));
|
||||
AudioPlayer.addShapes(Shapes.generatePolygon(4, new Vector2(-0.8, -0.8)));
|
||||
for (int i = 0; i < 10; i++) {
|
||||
AudioPlayer.addShape(new Ellipse(i / 10d, i / 10d));
|
||||
}
|
||||
|
||||
AudioPlayer.setRotateSpeed(0.8);
|
||||
AudioPlayer.setTranslation(2, new Vector(0.5, 0.5));
|
||||
AudioPlayer.setScale(0.5);
|
||||
|
||||
player.start();
|
||||
|
|
|
@ -2,7 +2,7 @@ package audio;
|
|||
|
||||
import com.xtaudio.xt.*;
|
||||
import shapes.Shape;
|
||||
import shapes.Vector;
|
||||
import shapes.Vector2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -17,7 +17,7 @@ public class AudioPlayer extends Thread {
|
|||
|
||||
public static XtFormat FORMAT;
|
||||
private static double TRANSLATE_SPEED = 0;
|
||||
private static Vector TRANSLATE_VECTOR;
|
||||
private static Vector2 TRANSLATE_VECTOR;
|
||||
private static final int TRANSLATE_PHASE_INDEX = 0;
|
||||
private static double ROTATE_SPEED = 0.4;
|
||||
private static final int ROTATE_PHASE_INDEX = 1;
|
||||
|
@ -81,7 +81,7 @@ public class AudioPlayer extends Thread {
|
|||
}
|
||||
|
||||
private static Shape translate(Shape shape, double sampleRate) {
|
||||
if (TRANSLATE_SPEED != 0 && !TRANSLATE_VECTOR.equals(new Vector())) {
|
||||
if (TRANSLATE_SPEED != 0 && !TRANSLATE_VECTOR.equals(new Vector2())) {
|
||||
return shape.translate(TRANSLATE_VECTOR.scale(
|
||||
Math.sin(nextTheta(sampleRate, TRANSLATE_SPEED, ROTATE_PHASE_INDEX))
|
||||
));
|
||||
|
@ -110,7 +110,7 @@ public class AudioPlayer extends Thread {
|
|||
AudioPlayer.ROTATE_SPEED = speed;
|
||||
}
|
||||
|
||||
public static void setTranslation(double speed, Vector translation) {
|
||||
public static void setTranslation(double speed, Vector2 translation) {
|
||||
AudioPlayer.TRANSLATE_SPEED = speed;
|
||||
AudioPlayer.TRANSLATE_VECTOR = translation;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
package engine;
|
||||
|
||||
import shapes.Line;
|
||||
import shapes.Vector2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Camera extends Renderer{
|
||||
|
||||
// position at 0,0,0,0
|
||||
// rotation towards positive z axis
|
||||
|
||||
private double focalLength;
|
||||
private double clipping = 0.001;
|
||||
private Vector3 position;
|
||||
private double fov;
|
||||
|
||||
public Camera() {
|
||||
this.focalLength = 0.6;
|
||||
this.position = new Vector3(0,0,-2);
|
||||
this.fov = 60;
|
||||
}
|
||||
|
||||
public List<Line> draw(WorldObject worldObject) {
|
||||
List<Vector2> vertices = new ArrayList<>();
|
||||
for(Vector3 vertex : worldObject.getVertices()) {
|
||||
vertices.add(this.project(vertex));
|
||||
}
|
||||
|
||||
return this.getFrame(vertices, worldObject.getEdgeData());
|
||||
}
|
||||
|
||||
private Vector2 project(Vector3 vertex) {
|
||||
if(vertex.getZ() - this.position.getZ() < clipping) {
|
||||
return new Vector2(0, 0);
|
||||
}
|
||||
return new Vector2(
|
||||
vertex.getX() * focalLength / (vertex.getZ() - this.position.getZ()) + this.position.getX(),
|
||||
vertex.getY() * focalLength / (vertex.getZ() - this.position.getZ()) + this.position.getY()
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package engine;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
Camera camera = new Camera();
|
||||
|
||||
WorldObject cube = new WorldObject("resources/machine.obj", new Vector3(0,0,0), new Vector3());
|
||||
while(true) {
|
||||
camera.draw(cube);
|
||||
cube.rotate(new Vector3(
|
||||
0,
|
||||
Math.PI / 100,
|
||||
0
|
||||
));
|
||||
Thread.sleep(1000/30);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
package engine;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
import java.util.regex.MatchResult;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class Mesh {
|
||||
|
||||
private static final String VERTEX_PATTERN = "(?m)^v .*";
|
||||
private static final String FACE_PATTERN = "(?m)^f .*";
|
||||
|
||||
private List<Vector3> vertices;
|
||||
private List<Integer> edgeData;
|
||||
|
||||
public Mesh() {
|
||||
this.vertices = new ArrayList<>();
|
||||
this.edgeData = new ArrayList<>();
|
||||
}
|
||||
|
||||
public Mesh(List<Vector3> vertices, List<Integer> edgeData) {
|
||||
this.vertices = vertices;
|
||||
this.edgeData = edgeData;
|
||||
}
|
||||
|
||||
public List<Vector3> getVertices() {
|
||||
return vertices;
|
||||
}
|
||||
|
||||
public List<Integer> getEdgeData() {
|
||||
return edgeData;
|
||||
}
|
||||
|
||||
public static Mesh loadFromFile(String filename) {
|
||||
Scanner sc;
|
||||
try {
|
||||
sc = new Scanner(new File(filename));
|
||||
} catch (Exception e) {
|
||||
System.err.println("Cannot load mesh data from: " + filename);
|
||||
return new Mesh();
|
||||
}
|
||||
// load vertices
|
||||
List<Vector3> vertices =
|
||||
sc.findAll(VERTEX_PATTERN)
|
||||
.map(s -> parseVertex(s.group(0)))
|
||||
.collect(Collectors.toList());
|
||||
// load edge data
|
||||
List<Integer> edgeData = new ArrayList<>();
|
||||
for(MatchResult result : sc.findAll(FACE_PATTERN).collect(Collectors.toList())) {
|
||||
List<Integer> indices = parseFace(result.group(0));
|
||||
for(int i = 0; i < indices.size(); i++ ) {
|
||||
edgeData.add(indices.get(i));
|
||||
edgeData.add(indices.get((i + 1) % indices.size()));
|
||||
}
|
||||
}
|
||||
return new Mesh(vertices, edgeData);
|
||||
}
|
||||
|
||||
private static Vector3 parseVertex(String data) {
|
||||
String[] coords = data.split(" ");
|
||||
double x = Double.parseDouble(coords[1]);
|
||||
double y = Double.parseDouble(coords[2]);
|
||||
double z = Double.parseDouble(coords[3]);
|
||||
return new Vector3(x, y, z);
|
||||
}
|
||||
|
||||
private static List<Integer> parseFace(String data) {
|
||||
List<Integer> indices = new ArrayList<>();
|
||||
String[] datas = data.split(" ");
|
||||
for(int i = 1; i < datas.length; i++) {
|
||||
indices.add(Integer.parseInt(datas[i].split("/")[0]) - 1);
|
||||
}
|
||||
return indices;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package engine;
|
||||
|
||||
import shapes.Line;
|
||||
import shapes.Vector2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class Renderer {
|
||||
public List<Line> getFrame(List<Vector2> vertices, List<Integer> connections) {
|
||||
List<Line> lines = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < connections.size(); i+=2) {
|
||||
Vector2 start = vertices.get(connections.get(i));
|
||||
Vector2 end = vertices.get(connections.get(i+1));
|
||||
double x1 = start.getX();
|
||||
double y1 = start.getY();
|
||||
double x2 = end.getX();
|
||||
double y2 = end.getY();
|
||||
|
||||
lines.add(new Line(x1, y1, x2, y2));
|
||||
}
|
||||
|
||||
return lines;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
package engine;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Vector3 {
|
||||
private double x, y, z;
|
||||
|
||||
public Vector3() {
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
this.z = 0;
|
||||
}
|
||||
|
||||
public Vector3(double x, double y, double z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public double getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
public Vector3 add(Vector3 other) {
|
||||
return new Vector3(
|
||||
this.getX() + other.getX(),
|
||||
this.getY() + other.getY(),
|
||||
this.getZ() + other.getZ()
|
||||
);
|
||||
}
|
||||
|
||||
public Vector3 scale(double scalar) {
|
||||
return new Vector3(
|
||||
this.getX() * scalar,
|
||||
this.getY() * scalar,
|
||||
this.getZ() * scalar
|
||||
);
|
||||
}
|
||||
|
||||
public Vector3 rotateX(double delta) {
|
||||
return new Vector3(
|
||||
getX(),
|
||||
Math.cos(delta) * getY() - Math.sin(delta) * getZ(),
|
||||
Math.sin(delta) * getY() + Math.cos(delta) * getZ()
|
||||
);
|
||||
}
|
||||
|
||||
public Vector3 rotateY(double delta) {
|
||||
return new Vector3(
|
||||
Math.cos(delta) * getX() + Math.sin(delta) * getZ(),
|
||||
getY(),
|
||||
-Math.sin(delta) * getX() + Math.cos(delta) * getZ()
|
||||
);
|
||||
}
|
||||
|
||||
public Vector3 rotateZ(double delta) {
|
||||
return new Vector3(
|
||||
Math.cos(delta) * getX() - Math.sin(delta) * getY(),
|
||||
Math.sin(delta) * getX() + Math.cos(delta) * getY(),
|
||||
getZ()
|
||||
);
|
||||
}
|
||||
|
||||
public static Vector3 meanPoint(List<Vector3> points) {
|
||||
Vector3 mean = new Vector3();
|
||||
for(Vector3 point : points) {
|
||||
mean = mean.add(point);
|
||||
}
|
||||
return mean.scale(1f / (points.size()));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package engine;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class WorldObject {
|
||||
|
||||
private Mesh mesh;
|
||||
private Vector3 position;
|
||||
private Vector3 rotation;
|
||||
|
||||
public WorldObject(String filename, Vector3 position, Vector3 rotation) {
|
||||
this.mesh = Mesh.loadFromFile(filename);
|
||||
this.position = position;
|
||||
this.rotation = rotation;
|
||||
}
|
||||
|
||||
public void rotate(Vector3 theta) {
|
||||
this.rotation = this.rotation.add(theta);
|
||||
}
|
||||
|
||||
public List<Vector3> getVertices() {
|
||||
List<Vector3> vertices = new ArrayList<>();
|
||||
for(Vector3 vertex : mesh.getVertices()) {
|
||||
vertices.add(
|
||||
vertex
|
||||
.rotateX(this.rotation.getX())
|
||||
.rotateY(this.rotation.getY())
|
||||
.rotateZ(this.rotation.getY())
|
||||
.add(this.position));
|
||||
}
|
||||
return vertices;
|
||||
}
|
||||
|
||||
public List<Integer> getEdgeData() {
|
||||
return mesh.getEdgeData();
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
package graphs;
|
||||
|
||||
import shapes.Line;
|
||||
import shapes.Vector;
|
||||
import shapes.Vector2;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
@ -10,7 +10,7 @@ import java.util.Map;
|
|||
// TODO: Implement Chinese postman solving.
|
||||
|
||||
public class Graph {
|
||||
private Map<Vector, Node> nodes;
|
||||
private Map<Vector2, Node> nodes;
|
||||
|
||||
public Graph(List<Line> lines) {
|
||||
this.nodes = new HashMap<>();
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
package graphs;
|
||||
|
||||
import shapes.Vector;
|
||||
import shapes.Vector2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class Node {
|
||||
private Vector location;
|
||||
private Vector2 location;
|
||||
private List<Node> adjacentNodes;
|
||||
private List<Double> adjacentWeights;
|
||||
|
||||
public Node(Vector location) {
|
||||
public Node(Vector2 location) {
|
||||
this.location = location;
|
||||
this.adjacentNodes = new ArrayList<>();
|
||||
this.adjacentWeights = new ArrayList<>();
|
||||
}
|
||||
|
||||
public Vector getLocation() {
|
||||
public Vector2 getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,9 +4,9 @@ public class Ellipse extends Shape {
|
|||
private final double a;
|
||||
private final double b;
|
||||
private final double rotation;
|
||||
private final Vector position;
|
||||
private final Vector2 position;
|
||||
|
||||
public Ellipse(double a, double b, double weight, double rotation, Vector position) {
|
||||
public Ellipse(double a, double b, double weight, double rotation, Vector2 position) {
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
this.weight = weight;
|
||||
|
@ -16,12 +16,12 @@ public class Ellipse extends Shape {
|
|||
this.length = 2 * Math.PI * Math.sqrt((a * a + b * b) / 2);
|
||||
}
|
||||
|
||||
public Ellipse(double a, double b, Vector position) {
|
||||
public Ellipse(double a, double b, Vector2 position) {
|
||||
this(a, b, 100, 0, position);
|
||||
}
|
||||
|
||||
public Ellipse(double a, double b) {
|
||||
this(a, b, 100, 0, new Vector());
|
||||
this(a, b, 100, 0, new Vector2());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -53,7 +53,7 @@ public class Ellipse extends Shape {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Shape translate(Vector vector) {
|
||||
public Shape translate(Vector2 vector) {
|
||||
return new Ellipse(a, b, weight, rotation, position.add(vector));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
package shapes;
|
||||
|
||||
public class Line extends Shape {
|
||||
private final Vector a;
|
||||
private final Vector b;
|
||||
private final Vector2 a;
|
||||
private final Vector2 b;
|
||||
|
||||
public static final double DEFAULT_WEIGHT = 100;
|
||||
|
||||
public Line(Vector a, Vector b, double weight) {
|
||||
public Line(Vector2 a, Vector2 b, double weight) {
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
this.weight = weight;
|
||||
this.length = calculateLength();
|
||||
}
|
||||
|
||||
public Line(Vector a, Vector b) {
|
||||
public Line(Vector2 a, Vector2 b) {
|
||||
this(a, b, DEFAULT_WEIGHT);
|
||||
}
|
||||
|
||||
public Line(double x1, double y1, double x2, double y2, double weight) {
|
||||
this(new Vector(x1, y1), new Vector(x2, y2), weight);
|
||||
this(new Vector2(x1, y1), new Vector2(x2, y2), weight);
|
||||
}
|
||||
|
||||
public Line(double x1, double y1, double x2, double y2) {
|
||||
this(new Vector(x1, y1), new Vector(x2, y2));
|
||||
this(new Vector2(x1, y1), new Vector2(x2, y2));
|
||||
}
|
||||
|
||||
private double calculateLength() {
|
||||
|
@ -35,7 +35,7 @@ public class Line extends Shape {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Line translate(Vector vector) {
|
||||
public Line translate(Vector2 vector) {
|
||||
return new Line(getA().add(vector), getB().add(vector));
|
||||
}
|
||||
|
||||
|
@ -58,11 +58,11 @@ public class Line extends Shape {
|
|||
return (float) (getY1() + (getY2() - getY1()) * drawingProgress);
|
||||
}
|
||||
|
||||
public Vector getA() {
|
||||
public Vector2 getA() {
|
||||
return a;
|
||||
}
|
||||
|
||||
public Vector getB() {
|
||||
public Vector2 getB() {
|
||||
return b;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ public abstract class Shape {
|
|||
public abstract float nextY(double drawingProgress);
|
||||
public abstract Shape rotate(double theta);
|
||||
public abstract Shape scale(double factor);
|
||||
public abstract Shape translate(Vector vector);
|
||||
public abstract Shape translate(Vector2 vector);
|
||||
|
||||
public double getWeight() {
|
||||
return weight;
|
||||
|
|
|
@ -4,11 +4,11 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
public class Shapes {
|
||||
public static List<Shape> generatePolygram(int sides, int angleJump, Vector start, double weight) {
|
||||
public static List<Shape> generatePolygram(int sides, int angleJump, Vector2 start, double weight) {
|
||||
List<Shape> polygon = new ArrayList<>();
|
||||
|
||||
double theta = angleJump * 2 * Math.PI / sides;
|
||||
Vector rotated = start.rotate(theta);
|
||||
Vector2 rotated = start.rotate(theta);
|
||||
polygon.add(new Line(start, rotated, weight));
|
||||
|
||||
while (!rotated.equals(start)) {
|
||||
|
@ -20,32 +20,32 @@ public class Shapes {
|
|||
return polygon;
|
||||
}
|
||||
|
||||
public static List<Shape> generatePolygram(int sides, int angleJump, Vector start) {
|
||||
public static List<Shape> generatePolygram(int sides, int angleJump, Vector2 start) {
|
||||
return generatePolygram(sides, angleJump, start, Line.DEFAULT_WEIGHT);
|
||||
}
|
||||
|
||||
public static List<Shape> generatePolygram(int sides, int angleJump, double scale, double weight) {
|
||||
return generatePolygram(sides, angleJump, new Vector(scale, scale), weight);
|
||||
return generatePolygram(sides, angleJump, new Vector2(scale, scale), weight);
|
||||
}
|
||||
|
||||
public static List<Shape> generatePolygram(int sides, int angleJump, double scale) {
|
||||
return generatePolygram(sides, angleJump, new Vector(scale, scale));
|
||||
return generatePolygram(sides, angleJump, new Vector2(scale, scale));
|
||||
}
|
||||
|
||||
public static List<Shape> generatePolygon(int sides, Vector start, double weight) {
|
||||
public static List<Shape> generatePolygon(int sides, Vector2 start, double weight) {
|
||||
return generatePolygram(sides, 1, start, weight);
|
||||
}
|
||||
|
||||
public static List<Shape> generatePolygon(int sides, Vector start) {
|
||||
public static List<Shape> generatePolygon(int sides, Vector2 start) {
|
||||
return generatePolygram(sides, 1, start);
|
||||
}
|
||||
|
||||
public static List<Shape> generatePolygon(int sides, double scale, double weight) {
|
||||
return generatePolygon(sides, new Vector(scale, scale), weight);
|
||||
return generatePolygon(sides, new Vector2(scale, scale), weight);
|
||||
}
|
||||
|
||||
public static List<Shape> generatePolygon(int sides, double scale) {
|
||||
return generatePolygon(sides, new Vector(scale, scale));
|
||||
return generatePolygon(sides, new Vector2(scale, scale));
|
||||
}
|
||||
|
||||
public static List<Line> cleanupLines(List<Line> lines) {
|
||||
|
|
|
@ -2,18 +2,18 @@ package shapes;
|
|||
|
||||
import java.util.Objects;
|
||||
|
||||
public class Vector {
|
||||
public class Vector2 {
|
||||
private final double x;
|
||||
private final double y;
|
||||
|
||||
private static final double EPSILON = 0.001;
|
||||
|
||||
public Vector(double x, double y) {
|
||||
public Vector2(double x, double y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public Vector() {
|
||||
public Vector2() {
|
||||
this(0, 0);
|
||||
}
|
||||
|
||||
|
@ -25,28 +25,28 @@ public class Vector {
|
|||
return y;
|
||||
}
|
||||
|
||||
public Vector setX(double x) {
|
||||
return new Vector(x, this.y);
|
||||
public Vector2 setX(double x) {
|
||||
return new Vector2(x, this.y);
|
||||
}
|
||||
|
||||
public Vector setY(double y) {
|
||||
return new Vector(this.x, y);
|
||||
public Vector2 setY(double y) {
|
||||
return new Vector2(this.x, y);
|
||||
}
|
||||
|
||||
public Vector add(Vector vector) {
|
||||
return new Vector(getX() + vector.getX(), getY() + vector.getY());
|
||||
public Vector2 add(Vector2 vector) {
|
||||
return new Vector2(getX() + vector.getX(), getY() + vector.getY());
|
||||
}
|
||||
|
||||
public Vector scale(double factor) {
|
||||
return new Vector(getX() * factor, getY() * factor);
|
||||
public Vector2 scale(double factor) {
|
||||
return new Vector2(getX() * factor, getY() * factor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) {
|
||||
return true;
|
||||
} else if (obj instanceof Vector) {
|
||||
Vector vector = (Vector) obj;
|
||||
} else if (obj instanceof Vector2) {
|
||||
Vector2 vector = (Vector2) obj;
|
||||
|
||||
return approxEquals(vector.getX(), getX()) && approxEquals(vector.getY(), getY());
|
||||
} else {
|
||||
|
@ -63,12 +63,12 @@ public class Vector {
|
|||
return Math.round(d * 1000) / 1000d;
|
||||
}
|
||||
|
||||
public Vector copy() {
|
||||
return new Vector(x, y);
|
||||
public Vector2 copy() {
|
||||
return new Vector2(x, y);
|
||||
}
|
||||
|
||||
public Vector rotate(double theta) {
|
||||
Vector vector = setX(getX() * Math.cos(theta) - getY() * Math.sin(theta));
|
||||
public Vector2 rotate(double theta) {
|
||||
Vector2 vector = setX(getX() * Math.cos(theta) - getY() * Math.sin(theta));
|
||||
vector = vector.setY(getX() * Math.sin(theta) + getY() * Math.cos(theta));
|
||||
|
||||
return vector;
|
Ładowanie…
Reference in New Issue