Skip to content

Commit fcb5c0f

Browse files
committed
getNormal implemented
1 parent 64a6957 commit fcb5c0f

File tree

6 files changed

+45
-11
lines changed

6 files changed

+45
-11
lines changed

src/geometries/Cylinder.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package geometries;
22

33
import primitives.*;
4+
5+
import static primitives.Util.alignZero;
46
import static primitives.Util.isZero;
57

68
/**
@@ -38,7 +40,31 @@ public double getHeight() {
3840

3941
@Override
4042
public Vector getNormal(Point point) {
41-
return null;
43+
Point bottomPoint = this.axisRay.getStartPoint();
44+
Vector dir = this.axisRay.getDirection();
45+
46+
if (point.equals(bottomPoint)) // Check if the point is the bottom center point of the cylinder
47+
return dir.scale(-1); // Returns the vector, opposite to the axis direction vector
48+
49+
if (point.equals(dir.scale(this.height))) // Check if the point is the top center point of the cylinder
50+
return dir;
51+
52+
// Get the projection created by the axis vector and the vector between the top center point and the point
53+
double projection = alignZero(dir.dotProduct(point.subtract(bottomPoint.add(dir.scale(this.height)))));
54+
if (isZero(projection))
55+
return dir; // If the projection is 0, it means that the point is on the top part of the cylinder
56+
57+
// Get the projection created by the axis vector and the vector between the bottom center point and the point
58+
projection = alignZero(dir.dotProduct(point.subtract(bottomPoint)));
59+
if (isZero(projection))
60+
return dir.scale(-1); // If the projection is 0, it means that the point is on the top part
61+
// of the cylinder
62+
63+
// Otherwise, the point is on the side of the cylinder
64+
// NOTE: I use bottomPoint to save the orthogonal point on the ray and not create a new variable in order
65+
// not to harm performance
66+
bottomPoint = bottomPoint.add(dir.scale(projection));
67+
return point.subtract(bottomPoint).normalize();
4268
}
4369

4470
@Override

src/geometries/Plane.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public class Plane implements Geometry {
2020
*/
2121
public Plane(Point p1, Point p2, Point p3) {
2222
this.q0 = p1;
23-
this.normal = null; // As for stage 1
23+
this.normal = p1.subtract(p2).crossProduct(p1.subtract(p3)).normalize();
2424
}
2525

2626
/**
@@ -45,7 +45,7 @@ public Vector getNormal() {
4545

4646
@Override
4747
public Vector getNormal(Point point) {
48-
return null;
48+
return this.normal;
4949
}
5050

5151
@Override

src/geometries/Sphere.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public double getRadius() {
4141

4242
@Override
4343
public Vector getNormal(Point point) {
44-
return null;
44+
return point.subtract(this.center).normalize();
4545
}
4646

4747
@Override

src/geometries/Tube.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
import primitives.*;
44

5+
import static primitives.Util.isZero;
6+
import static primitives.Util.alignZero;
7+
58
/**
69
* This class is the base for all classes using tubes
710
*
@@ -32,7 +35,12 @@ public Ray getAxisRay() {
3235

3336
@Override
3437
public Vector getNormal(Point point) {
35-
return null;
38+
Point rayPoint = this.axisRay.getStartPoint();
39+
Vector dir = this.axisRay.getDirection();
40+
double projection = alignZero(dir.dotProduct(point.subtract(rayPoint)));
41+
42+
rayPoint = isZero(projection) ? rayPoint : rayPoint.add(dir.scale(projection));
43+
return point.subtract(rayPoint).normalize();
3644
}
3745

3846
@Override

unittests/geometries/PlaneTest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@ void testConstructor() {
2222
// TC10: Test when 2 points are the same
2323
assertThrows(
2424
IllegalArgumentException.class,
25-
()->new Plane(p, p, new Point(0, 0, 1)),
25+
() -> new Plane(p, p, new Point(0, 0, 1)),
2626
"ERROR: ctor() does not throw an exception when 2 points are the same"
2727
);
2828

2929
// TC11: Test when all 3 points are on the same line
3030
assertThrows(
3131
IllegalArgumentException.class,
32-
()->new Plane(p, new Point(2, 0, 0), new Point(3, 0, 0)),
32+
() -> new Plane(p, new Point(2, 0, 0), new Point(3, 0, 0)),
3333
"ERROR: ctor() does not throw an exception when all 3 points are on the same line"
3434
);
3535
}
@@ -51,8 +51,8 @@ void testGetNormal() {
5151

5252
assertEquals(1, normal.length(), "ERROR: getNormal() vector is not the unit vector");
5353
assertTrue(
54-
normal.equals(new Vector(1, 1, 1)) ||
55-
normal.equals(new Vector(-1, -1, -1)),
54+
normal.equals(new Vector(1, 1, 1).normalize()) ||
55+
normal.equals(new Vector(-1, -1, -1).normalize()),
5656
"ERROR: getNormal() wrong value");
5757
}
5858
}

unittests/geometries/TriangleTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ void testGetNormal() {
2828

2929
assertEquals(1, normal.length(), "ERROR: getNormal() vector is not the unit vector");
3030
assertTrue(
31-
normal.equals(new Vector(1, 1, 1)) ||
32-
normal.equals(new Vector(-1, -1, -1)),
31+
normal.equals(new Vector(1, 1, 1).normalize()) ||
32+
normal.equals(new Vector(-1, -1, -1).normalize()),
3333
"ERROR: getNormal() wrong value");
3434
}
3535
}

0 commit comments

Comments
 (0)