Better JavaDoc
[sixth-3d.git] / src / main / java / eu / svjatoslav / sixth / e3d / renderer / raster / shapes / basic / texturedpolygon / PolygonBorderInterpolator.java
1 /*
2  * Sixth 3D engine. Author: Svjatoslav Agejenko.
3  * This project is released under Creative Commons Zero (CC0) license.
4  */
5 package eu.svjatoslav.sixth.e3d.renderer.raster.shapes.basic.texturedpolygon;
6
7 import eu.svjatoslav.sixth.e3d.geometry.Point2D;
8
9 import static java.lang.Math.abs;
10
11 /**
12  * Interpolator for textured polygon edges with perspective correction.
13  * <p>
14  * This class maps screen coordinates to texture coordinates while maintaining
15  * perspective accuracy.
16  * It's used to create texture-mapped scanlines that adjust for depth (z) to
17  * prevent texture distortion.
18  * <p>
19  * The comparison logic ensures proper scanline ordering based on vertical
20  * coverage and horizontal span.
21  */
22 public class PolygonBorderInterpolator implements
23         Comparable<PolygonBorderInterpolator> {
24
25     // on-screen coordinates
26     Point2D onScreenPoint1;
27     Point2D onScreenPoint2;
28
29     double distanceFromY1;
30     private int onScreenHeight;
31     private int onScreenWidth;
32     private int onscreenAbsoluteHeight;
33     private double textureWidth;
34     private double textureHeight;
35     // texture coordinates
36     private Point2D texturePoint1;
37     private Point2D texturePoint2;
38
39
40     @Override
41     public boolean equals(final Object o) {
42         if (o == null) return false;
43
44         return o instanceof PolygonBorderInterpolator && compareTo((PolygonBorderInterpolator) o) == 0;
45     }
46
47     @Override
48     public int hashCode() {
49         int result = onScreenWidth;
50         result = 31 * result + onscreenAbsoluteHeight;
51         return result;
52     }
53
54     @Override
55     public int compareTo(final PolygonBorderInterpolator otherInterpolator) {
56         if (onscreenAbsoluteHeight < otherInterpolator.onscreenAbsoluteHeight)
57             return 1;
58         if (onscreenAbsoluteHeight > otherInterpolator.onscreenAbsoluteHeight)
59             return -1;
60
61         if (onScreenWidth < otherInterpolator.onScreenWidth)
62             return 1;
63         if (onScreenWidth > otherInterpolator.onScreenWidth)
64             return -1;
65
66         return 0;
67     }
68
69     public boolean containsY(final int y) {
70
71         if (onScreenPoint1.y < onScreenPoint2.y) {
72             if (y >= onScreenPoint1.y)
73                 return y <= onScreenPoint2.y;
74         } else if (y >= onScreenPoint2.y)
75             return y <= onScreenPoint1.y;
76
77         return false;
78     }
79
80     public double getTX() {
81
82         if (onScreenHeight == 0)
83             return (texturePoint2.x + texturePoint1.x) / 2d;
84
85         return texturePoint1.x + ((textureWidth * distanceFromY1) / onScreenHeight);
86     }
87
88     public double getTY() {
89
90         if (onScreenHeight == 0)
91             return (texturePoint2.y + texturePoint1.y) / 2d;
92
93         return texturePoint1.y + ((textureHeight * distanceFromY1) / onScreenHeight);
94     }
95
96     public int getX() {
97
98         if (onScreenHeight == 0)
99             return (int) ((onScreenPoint2.x + onScreenPoint1.x) / 2d);
100
101         return (int) (onScreenPoint1.x + ((onScreenWidth * distanceFromY1) / onScreenHeight));
102     }
103
104     public void setCurrentY(final int y) {
105         distanceFromY1 = y - onScreenPoint1.y;
106     }
107
108     public void setPoints(final Point2D onScreenPoint1, final Point2D onScreenPoint2,
109                           final Point2D texturePoint1, final Point2D texturePoint2) {
110
111         this.onScreenPoint1 = onScreenPoint1;
112         this.onScreenPoint2 = onScreenPoint2;
113         this.texturePoint1 = texturePoint1;
114         this.texturePoint2 = texturePoint2;
115
116         onScreenHeight = (int) (onScreenPoint2.y - onScreenPoint1.y);
117         onScreenWidth = (int) (onScreenPoint2.x - onScreenPoint1.x);
118         onscreenAbsoluteHeight = abs(onScreenHeight);
119
120         textureWidth = texturePoint2.x - texturePoint1.x;
121         textureHeight = texturePoint2.y - texturePoint1.y;
122     }
123
124 }