Revision: | 2.1 |

Committed: | Tue Nov 12 17:00:46 1991 UTC (33 years ago) by greg |

Content type: | text/plain |

Branch: | MAIN |

Changes since 1.4: |
+0 -0 lines |

Log Message: | updated revision number for release 2.0 |

# | User | Rev | Content |
---|---|---|---|

1 | greg | 1.1 | /* Copyright (c) 1986 Regents of the University of California */ |

2 | |||

3 | #ifndef lint | ||

4 | static char SCCSid[] = "$SunId$ LBL"; | ||

5 | #endif | ||

6 | |||

7 | /* | ||

8 | * sphere.c - routines for creating octrees for spheres. | ||

9 | * | ||

10 | * 7/28/85 | ||

11 | */ | ||

12 | |||

13 | #include "standard.h" | ||

14 | |||

15 | #include "octree.h" | ||

16 | |||

17 | #include "object.h" | ||

18 | |||

19 | #include "otypes.h" | ||

20 | |||

21 | #define ROOT3 1.732050808 | ||

22 | |||

23 | /* | ||

24 | * Regrettably, the algorithm for determining a cube's location | ||

25 | * with respect to a sphere is not simple. First, a quick test is | ||

26 | * made to determine if the sphere and the bounding sphere of the cube | ||

27 | * are disjoint. This of course means no intersection. Failing this, | ||

28 | * we determine if the cube lies inside the sphere. The cube is | ||

29 | * entirely inside if the bounding sphere on the cube is | ||

30 | * contained within our sphere. This means no intersection. Otherwise, | ||

31 | * if the cube radius is smaller than the sphere's and the cube center is | ||

32 | * inside the sphere, we assume intersection. If these tests fail, | ||

33 | * we proceed as follows. | ||

34 | * The sphere center is located in relation to the 6 cube faces, | ||

35 | * and one of four things is done depending on the number of | ||

36 | * planes the center lies between: | ||

37 | * | ||

38 | * 0: The sphere is closest to a cube corner, find the | ||

39 | * distance to that corner. | ||

40 | * | ||

41 | * 1: The sphere is closest to a cube edge, find this | ||

42 | * distance. | ||

43 | * | ||

44 | * 2: The sphere is closest to a cube face, find the distance. | ||

45 | * | ||

46 | * 3: The sphere has its center inside the cube. | ||

47 | * | ||

48 | * In cases 0-2, if the closest part of the cube is within | ||

49 | * the radius distance from the sphere center, we have intersection. | ||

50 | * If it is not, the cube must be outside the sphere. | ||

51 | * In case 3, there must be intersection, and no further | ||

52 | * tests are necessary. | ||

53 | */ | ||

54 | |||

55 | |||

56 | o_sphere(o, cu) /* determine if sphere intersects cube */ | ||

57 | OBJREC *o; | ||

58 | register CUBE *cu; | ||

59 | { | ||

60 | FVECT v1; | ||

61 | double d1, d2; | ||

62 | greg | 1.4 | register FLOAT *fa; |

63 | greg | 1.1 | register int i; |

64 | #define cent fa | ||

65 | #define rad fa[3] | ||

66 | /* get arguments */ | ||

67 | greg | 1.3 | if (o->oargs.nfargs != 4) |

68 | objerror(o, USER, "bad # arguments"); | ||

69 | greg | 1.1 | fa = o->oargs.farg; |

70 | greg | 1.3 | if (rad < -FTINY) { |

71 | objerror(o, WARNING, "negative radius"); | ||

72 | o->otype = o->otype == OBJ_SPHERE ? | ||

73 | OBJ_BUBBLE : OBJ_SPHERE; | ||

74 | rad = -rad; | ||

75 | } else if (rad <= FTINY) | ||

76 | objerror(o, USER, "zero radius"); | ||

77 | greg | 1.1 | |

78 | d1 = ROOT3/2.0 * cu->cusize; /* bounding radius for cube */ | ||

79 | |||

80 | d2 = cu->cusize * 0.5; /* get distance between centers */ | ||

81 | for (i = 0; i < 3; i++) | ||

82 | v1[i] = cu->cuorg[i] + d2 - cent[i]; | ||

83 | d2 = DOT(v1,v1); | ||

84 | |||

85 | if (d2 > (rad+d1+FTINY)*(rad+d1+FTINY)) /* quick test */ | ||

86 | greg | 1.2 | return(O_MISS); /* cube outside */ |

87 | greg | 1.1 | |

88 | /* check sphere interior */ | ||

89 | if (d1 < rad) { | ||

90 | if (d2 < (rad-d1-FTINY)*(rad-d1-FTINY)) | ||

91 | greg | 1.2 | return(O_MISS); /* cube inside sphere */ |

92 | greg | 1.1 | if (d2 < (rad+FTINY)*(rad+FTINY)) |

93 | greg | 1.2 | return(O_HIT); /* cube center inside */ |

94 | greg | 1.1 | } |

95 | /* find closest distance */ | ||

96 | for (i = 0; i < 3; i++) | ||

97 | if (cent[i] < cu->cuorg[i]) | ||

98 | v1[i] = cu->cuorg[i] - cent[i]; | ||

99 | else if (cent[i] > cu->cuorg[i] + cu->cusize) | ||

100 | v1[i] = cent[i] - (cu->cuorg[i] + cu->cusize); | ||

101 | else | ||

102 | v1[i] = 0; | ||

103 | /* final intersection check */ | ||

104 | if (DOT(v1,v1) <= (rad+FTINY)*(rad+FTINY)) | ||

105 | greg | 1.2 | return(O_HIT); |

106 | greg | 1.1 | else |

107 | greg | 1.2 | return(O_MISS); |

108 | greg | 1.1 | } |