I'm working on some vector math, and I need to calculate the normal vector of a polygon.
My code:
//p is a parameter, is a Vec2, second point on first line
double[][] vert = getVerticies(); //[any length, # of verticies][2]
for(int i = 0; i < vert.length; i++) {
Vec2 cm = Vec2.ZERO_VEC;//first point on first line, always is <0, 0> as it is the origin
Vec2 rcm = getCM(); // just used to get relative positions.
Vec2 v1 = cm.sub(new Vec2(vert[i])); //the first point in one of all edges of the shape, second line
Vec2 v2 = cm.sub(new Vec2(i == vert.length - 1 ? vert[0] : vert[i + 1])); // the second point on the second line.
double den = (v2.getY() - v1.getY()) * (p.getX() - cm.getX()) - (v2.getX() - v1.getX()) * (p.getY() - cm.getY());
if(den == 0D) {
continue;
}
double a = ((v2.getX() - v1.getX()) * (cm.getY() - v1.getY()) - (v2.getY() - v1.getY()) * (cm.getX() - v1.getX())) / den;
double b = ((p.getX() - cm.getX()) * (cm.getY() - v1.getY()) - (p.getY() - cm.getY()) * (cm.getX() - v1.getX())) / den;
if(a >= 0D && a <= 1D && b >= 0D && b <= 1D) {
Vec2 mid = v2.add(v2.sub(v1).scale(0.5D)); //this is just normal vector calculation stuff, I know the error isn't here, as if it was, it would return a non-unit-scale vector.
return mid.uscale(); //hats the vector, returns
}
}
return p; // return the parameter, second point on first line, used as a contingency, should never actually run, as the first line is fully contained in the lines were testing against
I've done some debugging, and I just don't see what's happening. Can anyone tell me what's wrong with my math? It just seems to flow absolutely fine, but the math just doesn't seem right. My goal with this code is to determine the index of the two verticies that my line intersects.
Oops, figured it out by virtue of attempted to explain it. I need to be ray tracing, or use ray intersection testing.
If you are trying to calculate the normal of a polygon, it looks like you are trying to do something overly complicated. You can simply use cross product of two adjacent edges to get it. Even better, with a simple math explained here, you don't even need to calculate the edge vectors. Just take the cross product of each adjacent vertex pair and sum them up:
Related
I'm having some problems with a battleship solution I'm creating using Java. A random set of ships are loaded onto a 10x10 board. 1 2hit ships 2 3hit ships 1 4hit ship and 1 5hit ship (total of 17 hits goal)
I made a nested loop to basically fire at every cell coordinate until I either used 100 shots or destroyed all the ships. The GOAL is to find a way to sink all the ships with 50 or less shots. My problem is I can't tell where the ships are in accordance to their sink location (as it only tells me if I sunk a ship, not if I hit) Also, it doesn't tell me what kind of ship I've sunk, but I can figure that out a lot easier if I know how to solve the hit issue.
So how can I deduct if I've "hit" a ship? the only "hit" i can confirm on my board is the final shot triggered by the "a ship has sunk" message.
Edit: Sorry, I should also mention I do not have access to the battleship class, I only have a class I make that will be used to solve this problem. I was given some methods of the class such as:
" public BattleShip() - you need to call the constructor once in your program to create an instance of the battleship game.
public boolean shoot(Point shot) - you need to call this function to make each shot. See the sample source code for an example use.
public int numberOfShipsSunk() - returns the total number of ships sunk at any point during the game. It is a good idea to use this method to determine when a ship has been sunk.
public boolean allSunk() - returns a boolean value that indicates whether all the ships have been sunk.
public int totalShotsTaken() - returns the total number of shots taken. Your code needs to be responsible for ensuring the same shot is not taken more than once.
public ArrayList shipSizes() - returns an ArrayList of all of the ship sizes. The length of the array indicates how many ships are present.
public enum CellState - this enum object is very useful for marking cells has either Empty, Hit or Miss. It also has a convenience toString method so that can be used for printing purposes. You may also create your own Enum / Class for this in your code, but it is suggested that you use this instead of integers / characters to mark a Cell state"
The CellState property doesn't actually exist/is private so i can't use that. This is my loop.
x = 0;
for(int i = 0; i < 10; i++)
{
y = 0;
for(int j = 0; j < 10;j++)
{
if(x <=9 && y <=9) //X and Y are less than or equal to 9...
{
Point shot = new Point(x, y);
// At the end of each decision on where to fire next you need to shoot
if(shotTracker[x][y] == '-') // if space is free...
{ battleShip.shoot(shot);
if (sunkShip != battleShip.numberOfShipsSunk())
{
shotTracker[x][y] = 'O'; //The hit that sunk the ship
sunkShip++;
}
else
shotTracker[x][y] = '*'; // set space to fired miss
}
}
gameShots = battleShip.totalShotsTaken();
System.out.printf("You've shot %d times. The last shot's location was (%d,%d). You've hit something (not sure) times. You've sunk %d ships.\n", gameShots, x, y, battleShip.numberOfShipsSunk() );
if(battleShip.allSunk() || gameShots >= shotLimit)
{
break;
}
y+=3;
}
if(battleShip.allSunk() || gameShots >= shotLimit)
{
break;
}
x++;
}
if( gameShots >= shotLimit)
{
break;
}
}
And the output:
* - - * - - * - - *
* - - * - - * - - *
* - - * - - * - - *
* - - * - - * - - *
* - - * - - * - - *
* - - O - - * - - *
* - - * - - * - - *
* - - * - - * - - *
* - - * - - * - - *
This is a random output. I took a shot every 3 cells, and as you can see I sunk a ship but the O only tells me that was the finishing hit, so that was a vertical ship of unknown size on a random game...
Whatever code you are using to determine if a ship has been sunk should be able to tell you if a ship is hit. Otherwise, how does it aggregate to know its sunk?
I figured it out. My shot command
battleShip.shoot(shot)
evaluates to true or false, or hit or miss. When i check if true use "O" else use "*" O's pop up, so I guess I can do more work now. Thanks for trying to help!
I need for my java-program a function that checks for polygon-collision, but the algorithms (for point-in-polygon) I tried were not correct for my needs, the degenerative cases are a problem for me.
This is what i try to reach with my program: I have 2 polygons and want to put them nearest possible together. I want to place them on their vertices and rotate them along the edge to fit optimal. Therefor I need a collision-detection, if they intersect or not.
My biggest problem is that those polygon-edges could be on the same point. The researched algorithms decide if it is in polygon a or b (mostly with y-value).
What I use
Polygon with double coordinates for x and y
standard java
no external librarys
My required rules:
polygons can have same edge and same vertices (can be on same boundary, but not complete polygon overlay)
the edges should not be allowed to intersect
it is not allowed, that one polygon is completly surrounded by another polygon (a hole).
(an optional very small epsilon in algorithm would be good, because rotating with double is not very exact)
I tried too the internal classes like Path2D.Double() with contains too without success to this problem.
The last algorithm (of about minimum of 8) i tried was this:
wiki.cizmar.org/doku.php?id=physics:point-in-polygon_problem_with_simulation_of_simplicity
This is C Code of the linked algorithm (last one I tried)
int i, j, c = 0;
for (i = 0, j = number_of_vertices-1; i < number_of_vertices; j = i++) {
if ( ((vertices[i].y>p.y) != (vertices[j].y>p.y)) &&
(p.x < (vertices[j].x-vertices[i].x) * (p.y-vertices[i].y) / (vertices[j].y-vertices[i].y) + vertices[i].x) )
c = !c;
}
return c;
My adapted JAVA code (Punkt=Point, Form.getCoords = List of Coordinates with x,y)
private boolean testPointInsidePolygon3c(Punkt p, Form f){
int number_of_vertices = f.getCoords().size();
int i, j = 0;
boolean odd = false;
for (i = 0, j = number_of_vertices-1; i < number_of_vertices; j = i++) {
if ( ((f.getCoords().get(i).getY() >p.getY()) != (f.getCoords().get(j).getY() >p.getY())) &&
( p.getX() < (f.getCoords().get(j).getX() -f.getCoords().get(i).getX())
* (p.getY() -f.getCoords().get(i).getY())
/ (f.getCoords().get(j).getY() -f.getCoords().get(i).getY())
+ f.getCoords().get(i).getX())
){
odd = !odd;
}
}
return odd;
}
To show that problem: here are pictures with 2 polygons. the blue vertices are the troublesomes.
Problem Example #1 example from another source
I hope you got some ideas, links, algorithm or anything for me. i got stucked too long with that problem ;-)
What a pity - i could not do a complete correct algorithm, that solves my problem.
That is why I now use the JTS-Library!
With overlaps and covers/within i got everything correct in my test-cases.
I have an android application which is getting gesture coordinates (3 axis - x,y,z). I need to compare them with coordinates which I have in my DB and determine whether they are the same or not.
I also need to add some tolerance, since accelerometer (device which captures gestures) is very sensitive. It would be easy, but I also want to consider e.g. "big circle" drawn in the air, same as "small circle" drawn in the air. meaning that there would be different values, but structure of the graph would be the same, right?
I have heard about translating graph values into bits and then compare. Is that the right approach? Is there any library for such comparison?
So far I just hard coded it, covering all my requirements except the last one (big circle vs small circle).
My code now:
private int checkWhetherGestureMatches(byte[] values, String[] refValues) throws IOException {
int valuesSize = 32;
int ignorePositions = 4;
byte[] valuesX = new byte[valuesSize];
byte[] valuesY = new byte[valuesSize];
byte[] valuesZ = new byte[valuesSize];
for (int i = 0; i < valuesSize; i++) {
int position = i * 3 + ignorePositions;
valuesX[i] = values[position];
valuesY[i] = values[position + 1];
valuesZ[i] = values[position + 2];
}
Double[] valuesXprevious = new Double[valuesSize];
Double[] valuesYprevious = new Double[valuesSize];
Double[] valuesZprevious = new Double[valuesSize];
for (int i = 0; i < valuesSize; i++) {
int position = i * 3 + ignorePositions;
valuesXprevious[i] = Double.parseDouble(refValues[position]);
valuesYprevious[i] = Double.parseDouble(refValues[position + 1]);
valuesZprevious[i] = Double.parseDouble(refValues[position + 2]);
}
int incorrectPoints = 0;
for (int j = 0; j < valuesSize; j++) {
if (valuesX[j] < valuesXprevious[j] + 20 && valuesX[j] > valuesXprevious[j] - 20
&& valuesY[j] < valuesYprevious[j] + 20 && valuesY[j] > valuesYprevious[j] - 20
&& valuesZ[j] < valuesZprevious[j] + 20 && valuesZ[j] > valuesZprevious[j] - 20) {
} else {
incorrectPoints++;
}
}
return incorrectPoints;
}
EDIT:
I found JGraphT, it might work. If you know anything about that already, let me know.
EDIT2:
See these images, they are the same gesture but one is done in a slower motion than another.
Faster one:
Slower one:
I haven't captured images of the same gesture where one would be smaller than another, might add that later.
If your list of gestures is complex, I would suggest training a neural network which can classify the gestures based on the graph value bits you mentioned. The task is very similar to classification of handwritten numerical digits, for which lots of resources are there on the net.
The other approach would be to mathematically guess the shape of the gesture, but I doubt it will be useful considering the tolerance of the accelerometer and the fact that users won't draw accurate shapes.
(a) convert your 3D coordinates into 2D plain figure. Use matrix transformations.
(b) normalize your gesture scale - again with matrix transformations
(c) normalize the number of points or use interpolation on the next step.
(d) calculate the difference between your stored (s) gesture and current (c) gesture as
Sum((Xs[i] - Xc[i])^2 + (Ys[i] - Yc[i])^2) where i = 0 .. num of points
If the difference is below your predefined precision - gestures are equal.
I have used a Java implementation of Dynamic Time Wrapping algorithm. The library is called fastDTW.
Unfortunately from what I undersood they don't support it anymore, though I found a use for it.
https://code.google.com/p/fastdtw/
I can't recall now, but I think I used this one and compiled it myself:
https://github.com/cscotta/fastdtw/tree/master/src/main/java/com/fastdtw/dtw
In Java, I am trying to implement the following equation for calculating the current velocity of a skydiver not neglecting air resistance.
v(t) = v(t-∆t) + (g - [(drag x crossArea x airDensity) / (2*mass)] *
v[(t-∆t)^2] ) * (∆t)
My problem is that I am not sure how to translate "v(t - ∆t)" into a code. Right now I have this method below, where as you can see I am using the method within itself to find the previous velocity. This has continued to result in a stack overflow error message, understandably.
(timeStep = ∆t)
public double calculateVelocity(double time){
double velocity;
velocity = calculateVelocity(time - timeStep)
+ (acceleration - ((drag * crossArea * airDensity)
/ (2 * massOfPerson))
* (calculateVelocity(time - timeStep)*(time * timeStep)))
* timeStep;
}
return velocity;
}
I am calling the above method in the method below. Assuming that the ending time = an int, will be the user input but written this way to be dynamic.
public void assignVelocitytoArrays(){
double currentTime = 0;
while(currentTime <= endingTime){
this.vFinal = calculateVelocity(currentTime);
currentTime += timeStep;
}
}
I would like to figure this out on my own, could someone give me a general direction? Is using a method within itself the right idea or am I completely off track?
The formula you want to implement is the recursive representation of a sequence, mathematiacally speaking.
Recursive sequences need a starting point, e.g.
v(0) = 0 (because a negative time does not make sense)
and a rule to calculate the next elements, e.g.
v(t) = v(t-∆t) + (g - [(drag x crossArea x airDensity) / (2*mass)] * v[(t-∆t)^2] ) * (∆t)
(btw: are you sure it has to be v([t-∆t]^2) instead of v([t-∆t])^2?)
So your approach to use recursion (calling a function within itself) to calculate a recursive sequence is correct.
In your implementation, you only forgot one detail: the starting point. How should your program know that v(0) is not defined be the rule, but by a definite value? So you must include it:
if(input value == starting point){
return starting point
}
else{
follow the rule
}
On a side note: you seem to be creating an ascending array of velocities. It would make sense to use the already calculated values in the array instead of recursion, so you don't have to calculate every step again and again.
This only works if you did indeed make a mistake in the rule.
double[] v = new double[maxTime/timeStep];
v[0] = 0; //starting point
for(int t = 1; t < maxSteps; t++){
v[t] = v[t-1] + (g - [(drag x crossArea x airDensity) / (2*mass)] * v[t-1]^2 ) * (∆t)
}
i am trying to make my algorithm more efficient but for some reason its not working correctly could someone tell me if my logic is correct. The general problem is that if u have a height of 'x', and you can jump 'u' distance but you fall 'd' distance if you havent cleared the height already. i have to calculate the number of jumps.
Initial code works correctly
while(x-u>0) {
x=x-u+d;
i++;
}
i++;
more efficient code (for some reason fails some cases, I don't know which cases though)
int k=u-d;
if(x-u<=0){
i++;
} else {
int z=x/k;
if (x-((z-1)*k)-u <= 0) {
i+=z;
} else {
i=i+z+1;
}
}
let me try and clarify the problem you have a wall of height X, you can jump up distance U but every time you jump you also slip down distance D.
so lets say if u have a wall of height x=4, u=4, d=1. Then you would only have to jump once because the first time you jump you have cleared the wall, so you dont slip down at all. now lets say x=6, u=4,d=1. Then you would have to jump twice because the first time you would jump up to 4 but fall 1 so you are at 3 then the next jump you clear the wall.
Okay, let's see. The last jump comes from the height of x - u or higher. The rest you have to cover in (u - d)-size steps, the number of such steps is of course (x - u)/(u - d).
After i-th step you are at height i * (u - d) + u (and falling down). So, in approx. (x - u)/(u - d) steps you are at height x - u + u = x. Recalling that the number of steps should be a whole number, we get the final result:
if (u >= x)
return 1;
if (u <= d)
throw "Impossible";
return ceil((x - u)/(u - d));
(ceil is a mathematical function returning the smallest integer not less than the given number.)