Advertisement
ec1117

ray casting

Apr 7th, 2021
164
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.11 KB | None | 0 0
  1.  
  2. static final int SZ=600;
  3. static final int PAD=200;
  4. int rad=SZ/20;
  5. ArrayList<Rect> rect=new ArrayList<Rect>();
  6. ArrayList<Seg> seg=new ArrayList<Seg>();
  7. Point st;
  8.  
  9. color rectFill=#a888ce;
  10. color playerFill=#aba0e5;
  11. color playOutline=#a15497;
  12. color rays=#a66eb3;
  13. color back=#afb9fa;
  14.  
  15. boolean in(Point x){
  16. for(Rect y:rect){
  17. if(x.x>=y.l && x.x<=y.r && x.y>=y.u && x.y<=y.d){
  18. return true;
  19. }
  20. }
  21. //TODO: impl dist to seg
  22. return false;
  23. }
  24.  
  25. void setup(){
  26. size(600,600);
  27. int sepline=(int)random(SZ);
  28. while(sepline<PAD || sepline>SZ-PAD){
  29. sepline=(int)random(SZ);
  30. }
  31. //TODO: Constrain padding
  32. int u=(int)random(SZ), d=(int)random(SZ);
  33. int u2=(int)random(SZ), d2=(int)random(SZ);
  34. rect.add(new Rect((int)random(sepline),(int)random(sepline),u,d));
  35. rect.add(new Rect((int)random(SZ-sepline)+sepline,(int)random(SZ-sepline)+sepline,u2,d2));
  36. while(true){//not perfect
  37. st=new Point((int)random(SZ), (int)random(SZ));
  38. if(!in(st))break;
  39. }
  40. for(Rect x:rect){
  41. seg.add(new Seg(new Point(x.l,x.u),new Point(x.r,x.u)));
  42. seg.add(new Seg(new Point(x.l,x.d),new Point(x.r,x.d)));
  43. seg.add(new Seg(new Point(x.l,x.u),new Point(x.l,x.d)));
  44. seg.add(new Seg(new Point(x.r,x.u),new Point(x.r,x.d)));
  45. }
  46. seg.add(new Seg(new Point(0,0),new Point(SZ,0)));
  47. seg.add(new Seg(new Point(0,0),new Point(0,SZ)));
  48. seg.add(new Seg(new Point(SZ,0),new Point(SZ,SZ)));
  49. seg.add(new Seg(new Point(0,SZ),new Point(SZ,SZ)));
  50. }
  51.  
  52. float cross(PVector a, PVector b){
  53. return a.x*b.y-a.y*b.x;
  54. }
  55.  
  56. boolean intersect(Point a, Point b, Point c, Point d){
  57. PVector B=new PVector(b.x-a.x,b.y-a.y);
  58. PVector C=new PVector(c.x-a.x,c.y-a.y);
  59. PVector D=new PVector(d.x-a.x,d.y-a.y);
  60. float c1=cross(B,C);
  61. float c2=cross(B,D);
  62. int cc1=(int)(c1/abs(c1));
  63. int cc2=(int)(c2/abs(c2));
  64. //println(cc1+" "+cc2+" "+c1+" "+c2);
  65. if(cc1+cc2!=0){
  66. return false;
  67. }
  68. PVector A=new PVector(a.x-c.x,a.y-c.y);
  69. B=new PVector(b.x-c.x,b.y-c.y);
  70. D=new PVector(d.x-c.x,d.y-c.y);
  71. c1=cross(D,A);
  72. c2=cross(D,B);
  73. cc1=(int)(c1/abs(c1));
  74. cc2=(int)(c2/abs(c2));
  75. if(cc1+cc2!=0){
  76. return false;
  77. }
  78. return true;
  79. }
  80.  
  81. PVector castRay(PVector dir){//normalize first
  82. PVector mag=PVector.mult(dir,2*SZ);
  83. for(Seg x:seg){
  84. if(intersect(st,new Point(st.x+mag.x,st.y+mag.y),x.x,x.y)){
  85. float L=0,R=mag.mag();
  86. for(int i=0;i<30;i++){
  87. float M=(L+R)/2;
  88. PVector test=PVector.mult(dir,M);
  89. if(intersect(st,new Point(st.x+test.x,st.y+test.y),x.x,x.y)){
  90. R=M;
  91. } else L=M;
  92. }
  93. mag=PVector.mult(dir,L);
  94. }
  95. }
  96. return mag;
  97. }
  98.  
  99. void draw(){
  100. clear();
  101. background(back);
  102. move();
  103.  
  104. //line(st.x,st.y,mouseX,mouseY);
  105. PVector dir=new PVector(mouseX-st.x,mouseY-st.y);
  106. PVector ldir=new PVector(mouseX-st.x,mouseY-st.y);
  107. PVector rdir=new PVector(mouseX-st.x,mouseY-st.y);
  108. println(dir.heading());
  109. ldir.rotate(PI/6);
  110. rdir.rotate(-PI/6);
  111. dir.normalize();
  112. PVector mag=castRay(dir);
  113. PVector lmag=castRay(ldir);
  114. PVector rmag=castRay(rdir);
  115. //strokeWeight(1);
  116. //line(st.x,st.y,st.x+mag.x,st.y+mag.y);
  117. //line(st.x,st.y,st.x+lmag.x,st.y+lmag.y);
  118. //line(st.x,st.y,st.x+rmag.x,st.y+rmag.y);
  119. PVector prev=lmag;
  120. noStroke();
  121. fill(rays);
  122. for(int i=0;i<300;i++){
  123. PVector ray=new PVector(mouseX-st.x,mouseY-st.y);
  124. ray.rotate(-PI/6);
  125. ray.normalize();
  126. ray.rotate(PI/3/300*i);
  127. PVector raymag=castRay(ray);
  128. triangle(st.x,st.y,st.x+prev.x,st.y+prev.y,st.x+raymag.x,st.y+raymag.y);
  129. prev=raymag;
  130. }
  131.  
  132. fill(playerFill);
  133. strokeWeight(2);
  134. circle(st.x,st.y,rad);
  135. strokeWeight(3);
  136. fill(rectFill);
  137. for(Rect x:rect){
  138. rect(x.l,x.u,x.r-x.l,x.d-x.u);
  139. }
  140. }
  141.  
  142. final static float move=5;
  143. boolean isLeft,isRight,isDown,isUp;
  144.  
  145. void keyPressed(){
  146. setMove(keyCode,true);
  147. }
  148.  
  149. void keyReleased(){
  150. setMove(keyCode,false);
  151. }
  152.  
  153. void move(){
  154. float spd=move;
  155. if((isRight||isLeft) && (isDown||isUp)){
  156. spd/=1.41;
  157. }
  158. float x=constrain(st.x+spd*((int(isRight)-int(isLeft))),rad,SZ-rad);
  159. float y=constrain(st.y+spd*((int(isDown)-int(isUp))),rad,SZ-rad);
  160. if(!in(new Point(x,y))){
  161. st=new Point(x,y);
  162. } else if(!in(new Point(x,st.y))){
  163. st=new Point(x,st.y);
  164. } else if(!in(new Point(st.x,y))){
  165. st=new Point(st.x,y);
  166. }
  167. }
  168.  
  169. void setMove(final int code, boolean act){
  170. if(code==LEFT || code=='A'){
  171. isLeft=act;
  172. }
  173. if(code==UP || code=='W'){
  174. isUp=act;
  175. }
  176. if(code==DOWN || code=='S'){
  177. isDown=act;
  178. }
  179. if(code==RIGHT || code=='D'){
  180. isRight=act;
  181. }
  182. }
  183.  
  184. class Point{
  185. float x,y;
  186. Point(float a, float b){
  187. x=a;y=b;
  188. }
  189. }
  190.  
  191. class Seg{
  192. Point x, y;
  193. Seg(Point a, Point b){
  194. x=a;y=b;
  195. }
  196. }
  197.  
  198. class Rect{
  199. int l,r,u,d;
  200. Rect(int a, int b, int c, int e){
  201. if(c<=e){
  202. u=c;
  203. d=e;
  204. } else {
  205. u=e;
  206. d=c;
  207. }
  208. if(a<=b){
  209. l=a;
  210. r=b;
  211. } else {
  212. l=b;
  213. r=a;
  214. }
  215. }
  216. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement