Cleaner impact reactor explosion

This commit is contained in:
Anuken
2021-06-16 16:53:09 -04:00
parent a74bc0c077
commit 15affaad9b
3 changed files with 111 additions and 175 deletions

View File

@@ -97,12 +97,6 @@ public class Voronoi{
borderMaxY = maxY;
siteidx = 0;
Site newsite, bot, top, temp1, p;
Site v;
Vec2 newintstar = null;
int pm;
Halfedge lbnd, rbnd, llbnd, rrbnd, bisector;
Edge e;
PQcount = 0;
PQmin = 0;
@@ -129,7 +123,10 @@ public class Voronoi{
ELhash[ELhashsize - 1] = ELrightend;
bottomsite = next();
newsite = next();
Site newsite = next();
Halfedge lbnd;
Vec2 newintstar = null;
Edge e;
while(true){
if(PQcount != 0){
Vec2 answer = new Vec2();
@@ -142,24 +139,14 @@ public class Voronoi{
newintstar = (answer);
}
// if the lowest site has a smaller y value than the lowest vector
// intersection,
// process the site otherwise process the vector intersection
Halfedge rbnd;
Halfedge bisector;
Site p;
Site bot;
if(newsite != null
&& (PQcount == 0 || newsite.coord.y < newintstar.y || (newsite.coord.y == newintstar.y && newsite.coord.x < newintstar.x))){
/* new site is smallest -this is a site event */
// get the first HalfEdge to the LEFT of the new site
int i, bucket;
Halfedge he;
if(newsite != null && (PQcount == 0 || newsite.coord.y < newintstar.y || (newsite.coord.y == newintstar.y && newsite.coord.x < newintstar.x))){
int bucket = (int)(((newsite.coord).x - xmin) / deltax * ELhashsize);
/* Use hash table to get close to desired halfedge */
// use the hash function to find the place in the hash map that this
// HalfEdge should be
bucket = (int)(((newsite.coord).x - xmin) / deltax * ELhashsize);
// make sure that the bucket position in within the range of the hash
// array
if(bucket < 0){
bucket = 0;
}
@@ -167,12 +154,9 @@ public class Voronoi{
bucket = ELhashsize - 1;
}
he = getHash(bucket);
if(he == null)
// if the HE isn't found, search backwards and forwards in the hash map
// for the first non-null entry
{
for(i = 1; i < ELhashsize; i += 1){
Halfedge he = getHash(bucket);
if(he == null){
for(int i = 1; i < ELhashsize; i += 1){
if((he = getHash(bucket - i)) != null){
break;
}
@@ -181,137 +165,81 @@ public class Voronoi{
}
}
}
/* Now search linear list of halfedges for the correct one */
if(he == ELleftend || (he != ELrightend && right(he, (newsite.coord)))){
// keep going right on the list until either the end is reached, or
// you find the 1st edge which the point isn't to the right of
do{
he = he.ELright;
}while(he != ELrightend && right(he, (newsite.coord)));
he = he.ELleft;
}else
// if the point is to the left of the HalfEdge, then search left for
// the HE just to the left of the point
{
}else{
do{
he = he.ELleft;
}while(he != ELleftend && !right(he, (newsite.coord)));
}
/* Update hash table and reference counts */
if(bucket > 0 && bucket < ELhashsize - 1){
ELhash[bucket] = he;
}
lbnd = (he);
// get the first HalfEdge to the RIGHT of the new site
rbnd = (lbnd.ELright);
// if this halfedge has no edge,bot =bottom site (whatever that
// is)
lbnd = he;
rbnd = lbnd.ELright;
bot = rightreg(lbnd);
// create a new edge that bisects
e = bisect(bot, newsite);
// create a new HalfEdge, setting its ELpm field to 0
bisector = newHe(e, LE);
// insert this new bisector edge between the left and right
// vectors in a linked list
insert(lbnd, bisector);
// if the new bisector intersects with the left edge,
// remove the left edge's vertex, and put in the new one
if((p = intersect(lbnd, bisector)) != null){
pqdelete(lbnd);
pqinsert(lbnd, p, p.coord.dst(newsite.coord));
}
lbnd = bisector;
// create a new HalfEdge, setting its ELpm field to 1
bisector = newHe(e, RE);
// insert the new HE to the right of the original bisector
// earlier in the IF stmt
insert(lbnd, bisector);
// if this new bisector intersects with the new HalfEdge
if((p = intersect(bisector, rbnd)) != null){
// push the HE into the ordered linked list of vertices
pqinsert(bisector, p, p.coord.dst(newsite.coord));
}
newsite = next();
}else if(!(PQcount == 0))
/* intersection is smallest - this is a vector event */{
// pop the HalfEdge with the lowest vector off the ordered list
// of vectors
}else if(!(PQcount == 0)){
Halfedge curr;
curr = PQhash[PQmin].PQnext;
PQhash[PQmin].PQnext = curr.PQnext;
PQcount -= 1;
lbnd = (curr);
// get the HalfEdge to the left of the above HE
llbnd = (lbnd.ELleft);
// get the HalfEdge to the right of the above HE
rbnd = (lbnd.ELright);
// get the HalfEdge to the right of the HE to the right of the
// lowest HE
rrbnd = (rbnd.ELright);
// get the Site to the left of the left HE which it bisects
Halfedge llbnd = lbnd.ELleft;
rbnd = lbnd.ELright;
Halfedge rrbnd = (rbnd.ELright);
bot = leftReg(lbnd);
// get the Site to the right of the right HE which it bisects
top = rightreg(rbnd);
Site top = rightreg(rbnd);
v = lbnd.vertex; // get the vertex that caused this event
// set the vertex number - couldn't do this
Site v = lbnd.vertex;
v.sitenbr = nvertices;
nvertices += 1;
// earlier since we didn't know when it would be processed
endpoint(lbnd.ELedge, lbnd.ELpm, v);
// set the endpoint of
// the left HalfEdge to be this vector
endpoint(rbnd.ELedge, rbnd.ELpm, v);
// set the endpoint of the right HalfEdge to
// be this vector
delete(lbnd); // mark the lowest HE for
// deletion - can't delete yet because there might be pointers
// to it in Hash Map
delete(lbnd);
pqdelete(rbnd);
// remove all vertex events to do with the right HE
delete(rbnd); // mark the right HE for
// deletion - can't delete yet because there might be pointers
// to it in Hash Map
pm = LE; // set the pm variable to zero
delete(rbnd);
int pm = LE;
if(bot.coord.y > top.coord.y)
// if the site to the left of the event is higher than the
// Site
{ // to the right of it, then swap them and set the 'pm'
// variable to 1
temp1 = bot;
if(bot.coord.y > top.coord.y){
Site temp1 = bot;
bot = top;
top = temp1;
pm = RE;
}
e = bisect(bot, top); // create an Edge (or line)
// that is between the two Sites. This creates the formula of
// the line, and assigns a line number to it
bisector = newHe(e, pm); // create a HE from the Edge 'e',
// and make it point to that edge
// with its ELedge field
insert(llbnd, bisector); // insert the new bisector to the
// right of the left HE
endpoint(e, RE - pm, v); // set one endpoint to the new edge
// to be the vector point 'v'.
// If the site to the left of this bisector is higher than the
// right Site, then this endpoint
// is put in position 0; otherwise in pos 1
// if left HE and the new bisector intersect, then delete
// the left HE, and reinsert it
e = bisect(bot, top);
bisector = newHe(e, pm);
insert(llbnd, bisector);
endpoint(e, RE - pm, v);
if((p = intersect(llbnd, bisector)) != null){
pqdelete(llbnd);
pqinsert(llbnd, p, p.coord.dst(bot.coord));
}
// if right HE and the new bisector intersect, then
// reinsert it
if((p = intersect(bisector, rrbnd)) != null){
pqinsert(bisector, p, p.coord.dst(bot.coord));
}
@@ -333,10 +261,7 @@ public class Voronoi{
}
private Edge bisect(Site s1, Site s2){
float dx, dy, adx, ady;
Edge newedge;
newedge = new Edge();
Edge newedge = new Edge();
// store the sites that this edge is bisecting
newedge.reg[0] = s1;
@@ -347,11 +272,11 @@ public class Voronoi{
newedge.ep[1] = null;
// get the difference in x dist between the sites
dx = s2.coord.x - s1.coord.x;
dy = s2.coord.y - s1.coord.y;
float dx = s2.coord.x - s1.coord.x;
float dy = s2.coord.y - s1.coord.y;
// make sure that the difference in positive
adx = dx > 0 ? dx : -dx;
ady = dy > 0 ? dy : -dy;
float adx = dx > 0 ? dx : -dx;
float ady = dy > 0 ? dy : -dy;
newedge.c = s1.coord.x * dx + s1.coord.y * dy + (dx * dx + dy * dy) * 0.5f;// get the slope of the line
if(adx > ady){
@@ -367,7 +292,7 @@ public class Voronoi{
newedge.edgenbr = nedges;
nedges += 1;
return (newedge);
return newedge;
}
private int pqbucket(Halfedge he){
@@ -383,7 +308,7 @@ public class Voronoi{
if(bucket < PQmin){
PQmin = bucket;
}
return (bucket);
return bucket;
}
// push the HalfEdge into the ordered linked list of vertices
@@ -424,20 +349,20 @@ public class Voronoi{
answer.ELpm = pm;
answer.PQnext = null;
answer.vertex = null;
return (answer);
return answer;
}
private Site leftReg(Halfedge he){
if(he.ELedge == null){
return (bottomsite);
return bottomsite;
}
return (he.ELpm == LE ? he.ELedge.reg[LE] : he.ELedge.reg[RE]);
return he.ELpm == LE ? he.ELedge.reg[LE] : he.ELedge.reg[RE];
}
private void insert(Halfedge lb, Halfedge newHe){
newHe.ELleft = lb;
newHe.ELright = lb.ELright;
(lb.ELright).ELleft = newHe;
lb.ELright.ELleft = newHe;
lb.ELright = newHe;
}
@@ -446,8 +371,8 @@ public class Voronoi{
* may be present.
*/
private void delete(Halfedge he){
(he.ELleft).ELright = he.ELright;
(he.ELright).ELleft = he.ELleft;
he.ELleft.ELright = he.ELright;
he.ELright.ELleft = he.ELleft;
he.deleted = true;
}
@@ -591,27 +516,22 @@ public class Voronoi{
}
private boolean right(Halfedge el, Vec2 p){
Edge e;
Site topsite;
boolean right_of_site;
boolean above, fast;
float dxp, dyp, dxs, t1, t2, t3, yl;
e = el.ELedge;
topsite = e.reg[1];
right_of_site = p.x > topsite.coord.x;
if(right_of_site && el.ELpm == LE){
return (true);
Edge e = el.ELedge;
Site topsite = e.reg[1];
boolean rightOf = p.x > topsite.coord.x;
if(rightOf && el.ELpm == LE){
return true;
}
if(!right_of_site && el.ELpm == RE){
return (false);
if(!rightOf && el.ELpm == RE){
return false;
}
boolean above;
if(e.a == 1.0){
dyp = p.y - topsite.coord.y;
dxp = p.x - topsite.coord.x;
fast = false;
if((!right_of_site & (e.b < 0.0)) | (right_of_site & (e.b >= 0.0))){
float dyp = p.y - topsite.coord.y;
float dxp = p.x - topsite.coord.x;
boolean fast = false;
if((!rightOf & (e.b < 0.0)) | (rightOf & (e.b >= 0.0))){
above = dyp >= e.b * dxp;
fast = above;
}else{
@@ -624,18 +544,18 @@ public class Voronoi{
}
}
if(!fast){
dxs = topsite.coord.x - (e.reg[0]).coord.x;
float dxs = topsite.coord.x - (e.reg[0]).coord.x;
above = e.b * (dxp * dxp - dyp * dyp) < dxs * dyp
* (1.0 + 2.0 * dxp / dxs + e.b * e.b);
if(e.b < 0.0){
above = !above;
}
}
}else /* e.b==1.0 */{
yl = e.c - e.a * p.x;
t1 = p.y - yl;
t2 = p.x - topsite.coord.x;
t3 = yl - topsite.coord.y;
}else{
float yl = e.c - e.a * p.x;
float t1 = p.y - yl;
float t2 = p.x - topsite.coord.x;
float t3 = yl - topsite.coord.y;
above = t1 * t1 > t2 * t2 + t3 * t3;
}
return ((el.ELpm == LE) == above);
@@ -644,13 +564,9 @@ public class Voronoi{
private Site rightreg(Halfedge he){
if(he.ELedge == null) return bottomsite;
// if the ELpm field is zero, return the site 0 that this edge bisects,
// otherwise return site number 1
return (he.ELpm == LE ? he.ELedge.reg[RE] : he.ELedge.reg[LE]);
}
// create a new site where the HalfEdges el1 and el2 intersect - note that
// the Vec2 in the argument list is not used, don't know why it's there
private Site intersect(Halfedge el1, Halfedge el2){
Edge e1, e2, e;
Halfedge el;
@@ -664,7 +580,6 @@ public class Voronoi{
return null;
}
// if the two edges bisect the same parent, return null
if(e1.reg[1] == e2.reg[1]){
return null;
}
@@ -692,15 +607,12 @@ public class Voronoi{
return null;
}
// create a new site at the point of intersection - this is a new vector
// event waiting to happen
v = new Site();
v.coord.x = xint;
v.coord.y = yint;
return (v);
}
// used both for sites and for vertices
static class Site{
Vec2 coord = new Vec2();
int sitenbr;
@@ -724,8 +636,8 @@ public class Voronoi{
static class Edge{
float a = 0, b = 0, c = 0;
Site[] ep = new Site[2]; // JH: End points?
Site[] reg = new Site[2]; // JH: Sites this edge bisects?
Site[] ep = new Site[2];
Site[] reg = new Site[2];
int edgenbr;
}
}