⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gridsub2.c

📁 有限元学习研究用源代码(老外的),供科研人员参考
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
IGRID - Interactive Gridding Program.
Copyright (c) 1995 Thng Cheok Hoey

This program  is free software; you can redistribute it and /or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2 or License, or (at your option) any
later version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY of FIT-
NESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.

You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 675 Mass
Ave, Cambridge, MA 02139, USA.

Author's email address: thng@mimicad.colorado.edu
*/

#include <windows.h>
#include <math.h>                                        
#include <stdio.h>
#include <commdlg.h>
#include <stdlib.h>
#include <string.h>
#include "emgrid.h"
#include "geometry.h"
#include "mousemod.h"

extern HWND hwndMessage, hwndMessage2;
extern int         blockvacancy;
extern mousemode    *mouse;
extern OPENFILENAME ofn;
extern rectblk  *rectblockselected;
extern quadblk  *quadblockselected;
extern triblk   *triblockselected;
extern HWND   hwndMain, hwndPaper;
extern long   deskpixelwidth, deskpixelheight;
extern int    cxViewport, cyViewport;
extern double viewwidth, viewheight;
extern double deskwidth, deskheight;
extern double paperxcenter, paperycenter;
extern double paperwidth, paperheight;
extern double deskwidth, deskheight;
extern double xOffsetView, yOffsetView;
extern dRECT  papersize;
extern double unit;

extern HPEN   hPenDotBlack, hPenSolidBlack, hPenSolidYellow;
extern HPEN   hPenArray[];
extern HBRUSH hBrushNormal, hBrushHighlight;
extern char buffer[256];

void drawingtolp(POINT *, dPOINT);
void drawdottedrect(HDC, RECT);
void adjust(dRECT *);
void rotatepoint(dPOINT *, const double, const double);
void pixelresolution(dPOINT *);
void drawline(HDC, double, double, double, double);
double crossproduct(double, double, double, double);
double length(dPOINT, dPOINT);
double dotproduct(dPOINT, dPOINT);
void  calwindowcoord(void);
double crossproduct(dVECTOR, dVECTOR);

class block * nextblock(ID id);
COUNT  numberexteriorelmts(void);

extern tol option;
extern blocklist unselected, selected, addon, copied, swaped;

double winright, winleft, wintop, winbottom;

/*******************************************************************/
/*                                                                 */
/* Member functions for block                                      */
/*                                                                 */
/*******************************************************************/

int block::proximity(block *b1, int i, block *b2, int j){

    if(b1 == b2) return NO;
    if((b1->exteriornode[i].x > b2->exteriornode[j].x - option.snap) &&
       (b1->exteriornode[i].x < b2->exteriornode[j].x + option.snap) &&
       (b1->exteriornode[i].y > b2->exteriornode[j].y - option.snap) &&
       (b1->exteriornode[i].y < b2->exteriornode[j].y + option.snap)){
       // MessageBeep(0);
       return YES;
    }
    else
       return NO;
}

int block::connectednodes(int i, block *b2){

    ID destid;

    destid = b2->getid();
    if(exteriornode[i].cellid == destid) return YES;
    return NO;
}

int block::connectedsides(int i, block *b2){

    ID destid;

    destid = b2->getid();
    if(exteriorside[i].cellid == destid) return YES;
    return NO;
}



int block::connectednodes(int i, block *b, int j){

    int k;
    ID tmpid;
    block *destcell;

    if(b == this) return NO;

    destcell = this;
    k = i;
    tmpid = exteriornode[i].cellid;
    do{
      k = destcell->exteriornode[k].node;
      if((destcell = unselected.by_id(tmpid)) == NULL)
	if((destcell = selected.by_id(tmpid)) == NULL)
	  destcell = addon.by_id(tmpid);
      if((k == j) && (destcell == b)) return YES;
    }while(((tmpid = destcell->exteriornode[k].cellid) != id) ||
     (destcell->exteriornode[k].node != i));
    return NO;
}



void block::connectsides(int i, block *b, int j){

    int k, s;
    PRPTY destproperty;
    ID tmpid, destid, headid;
    block *destcell;

    destcell = b;
    destid = destcell->getid();

    destproperty = destcell->exteriorside[j].property & PROPERTYMASK;
    headid = exteriorside[i].cellid;
    s = exteriorside[i].side;
    exteriorside[i].cellid = destid;
    exteriorside[i].side = k = j;
    while(((tmpid = destcell->exteriorside[k].cellid) != destid) ||
	  (destcell->exteriorside[k].side != j)){
      destcell->exteriorside[k].property |= CONNECTMASK;

      k = destcell->exteriorside[k].side;
      if((destcell = unselected.by_id(tmpid)) == NULL)
	if((destcell = selected.by_id(tmpid)) == NULL)
	  destcell = addon.by_id(tmpid);

    }
    destcell->exteriorside[k].cellid = headid;
    destcell->exteriorside[k].side = s;
    destcell->exteriorside[k].property |= CONNECTMASK;


    do{
      tmpid = destcell->exteriorside[k].cellid;
      k = destcell->exteriorside[k].side;
      if((destcell = unselected.by_id(tmpid)) == NULL)
	if((destcell = selected.by_id(tmpid)) == NULL)
	  destcell = addon.by_id(tmpid);
      destcell->exteriorside[k].property &= (~PROPERTYMASK);
      destcell->exteriorside[k].property |= destproperty;
      destcell->exteriorside[k].property |= CONNECTMASK;
    }while((tmpid != id) || (k != i));
}


int block::modifyproperty(HDC hdc, dRECT drect){
    // drect must be adjust so that right > left, top > bottom

    int i, n, count = 0;
    double tmpx, tmpy;

    n = exteriorelmtcount();
    for(i = 0; i < n; i++){
      tmpx = exteriornode[i].x;
      tmpy = exteriornode[i].y;
      if((tmpx > drect.left)   && (tmpx < drect.right)&&
	 (tmpy > drect.bottom) && (tmpy < drect.top)){
	exteriornode[i].property &= (~PROPERTYMASK);
	exteriornode[i].property |= mouse->getproperty();     
	count++;
      }
      tmpx = 0.5 * (tmpx + exteriornode[(i+1)%n].x);
      tmpy = 0.5 * (tmpy + exteriornode[(i+1)%n].y);
      if((tmpx > drect.left)   && (tmpx < drect.right)&&
	 (tmpy > drect.bottom) && (tmpy < drect.top)){
	exteriorside[i].property &= (~PROPERTYMASK);
	exteriorside[i].property |= mouse->getproperty();
	count++;
      }
    }
    return count;

}



 block::modifyproperty(HDC hdc, dPOINT dp){
    // drect must be adjust so that right > left, top > bottom

    int i, j, n;
    dPOINT delrec;
    double tmpx, tmpy;
    ID tmpid;
    block *destcell;

    pixelresolution(&delrec);

    n = exteriorelmtcount();
    for(i = 0; i < n; i++){
      tmpx = exteriornode[i].x;
      tmpy = exteriornode[i].y;
      if((dp.x < tmpx + HOOKTOLERANCE * delrec.x) &&
	 (dp.x > tmpx - HOOKTOLERANCE * delrec.x) &&
	 (dp.y < tmpy + HOOKTOLERANCE * delrec.y) &&
	 (dp.y > tmpy - HOOKTOLERANCE * delrec.y)){
	exteriornode[i].property &= (~PROPERTYMASK);
	exteriornode[i].property |= mouse->getproperty();

	// update all the connected nodes to the new property

	destcell = this;
	j = i;
	while(((tmpid = destcell->exteriornode[j].cellid) != id) ||
	  (destcell->exteriornode[j].node != i)){
	  j = destcell->exteriornode[j].node;
	  if((destcell = unselected.by_id(tmpid)) == NULL)
	    if((destcell = selected.by_id(tmpid)) == NULL)
	      destcell = addon.by_id(tmpid);
	  destcell->exteriornode[j].property &= (~PROPERTYMASK);
	  destcell->exteriornode[j].property |= mouse->getproperty();
	}
	return 1;
      }
    }
    return 0;
}


// disconnect the exterior element of block from
// selected and unselected groups.
// result:
// each exterior element of block points to itself.
// The rest of the blocks remain connected. Their
// exterior elements point in loops when connected.

void block::disconnect(void){

    int i;
    listcell *hcell1, *hcell2;

    hcell1 = selected.gethead();
    hcell2 = unselected.gethead();
    for(i = 0; i < exteriorelmtcount(); i++){
      if(disconnectnodes(i, hcell1) == NO)
	disconnectnodes(i, hcell2);
      if(disconnectsides(i, hcell1) == NO)
	disconnectsides(i, hcell2);
    }
}

void block::clearconnectmask(void){

    int i;

    for(i = 0; i < exteriorelmtcount(); i++){
      exteriornode[i].property &= (~CONNECTMASK);
      exteriorside[i].property &= (~CONNECTMASK);
    }
}


COUNT block::connect(blocklist& targetlist){

    int i, ns;
    listcell *hcell;
    COUNT nscount = {0, 0, 0};

    hcell = targetlist.gethead();
    if(hcell == NULL) return nscount;
    for(i = 0; i < exteriorelmtcount(); i++){
      if(!(exteriornode[i].property & CONNECTMASK)){
	 ns = connectexteriornode(i, hcell);
	 nscount.node += ns;
      }
    }
    ns = connectexteriorside();
    nscount.side += ns;
    return nscount;
}



//  connect the i-th node of block to linklist headed by pcell.
//  all the connected node will be marked by CONNECTMASK BIT
//  0: nothing connect.
//  1: one node connected.

int block::connectexteriornode(int i, listcell *pcell){

    int j, k, m, n, connectcount = 0, headnode;
    ID  destid, tmpid, headid;
    PRPTY destproperty;
    block *destcell;

    while(pcell != NULL){
      destcell = pcell->cellblk;
      if(destcell == this){
	pcell = pcell->next;
	continue;
      }
      destid = destcell->getid();
      m = destcell->exteriorelmtcount();
      for(j = 0; j < m; j++){
	if(destcell->exteriornode[j].property & CONNECTMASK) continue;
	// this node is already connected
	if(proximity(this, i, destcell, j)){ // connect
	  destproperty = destcell->exteriornode[j].property & PROPERTYMASK;
	  headid = exteriornode[i].cellid;
	  headnode = exteriornode[i].node;
	  exteriornode[i].cellid = destid;
	  exteriornode[i].node = k = j;
	  while(((tmpid = destcell->exteriornode[k].cellid) != destid) ||
	    (destcell->exteriornode[k].node != j)){

	    destcell->exteriornode[k].property |= CONNECTMASK;
	    k = destcell->exteriornode[k].node;
	    if((destcell = unselected.by_id(tmpid)) == NULL)
	      if((destcell = selected.by_id(tmpid)) == NULL)
		destcell = addon.by_id(tmpid);
	  }
	  destcell->exteriornode[k].cellid = tmpid = headid;
	  destcell->exteriornode[k].node = headnode;
	  destcell->exteriornode[k].property |= CONNECTMASK;

	  // copy property attributes.
	  do{
	    tmpid = destcell->exteriornode[k].cellid;
	    k = destcell->exteriornode[k].node;
	    if((destcell = unselected.by_id(tmpid)) == NULL)
	      if((destcell = selected.by_id(tmpid)) == NULL)
		destcell = addon.by_id(tmpid);
	    destcell->exteriornode[k].property &= (~PROPERTYMASK);
	    destcell->exteriornode[k].property |= destproperty;
	    destcell->exteriornode[k].property |= CONNECTMASK;
	  }while((tmpid != id) || (k != i));

	  connectcount += 1;
	}
	if(connectcount > 0) break;
      }
      if(connectcount > 0) break;
      pcell = pcell->next;
    }
    return connectcount;
}


int block::connectexteriorside(void){

    int i, k, n, p, connectcount = 0;
    ID  destid, tmpid;
    block *destcell;

    p = exteriorelmtcount();

    for(i = 0; i < p; i++){
      if(!(exteriornode[i].property & CONNECTMASK)) continue;
      if(!(exteriornode[(i+1)%p].property & CONNECTMASK)) continue;
      if(exteriorside[i].property & CONNECTMASK) continue;
      tmpid = exteriornode[i].cellid;
      k = exteriornode[i].node;
      if((destcell = unselected.by_id(tmpid)) == NULL)
	if((destcell = selected.by_id(tmpid)) == NULL)
	  destcell = addon.by_id(tmpid);

      do{
	n = destcell->exteriorelmtcount();
	if((destcell->exteriornode[(k+n-1)%n].property & CONNECTMASK) &&
	   (!(destcell->exteriorside[(k+n-1)%n].property & CONNECTMASK)) &&
	   (connectednodes((i+1)%p, destcell, (k+n-1)%n))){
	   connectsides(i, destcell, (k+n-1)%n);
	   connectcount++;
	   break;
	}
	else if((destcell->exteriornode[(k+1)%n].property & CONNECTMASK) &&
	   (!(destcell->exteriorside[k].property & CONNECTMASK)) &&
	   (connectednodes((i+1)%p, destcell, (k+1)%n))){
	   connectsides(i, destcell, k);
	   connectcount++;
	   break;
	}

	// get blk-pointer from id
	tmpid = destcell->exteriornode[k].cellid;
	k = destcell->exteriornode[k].node;
	if((destcell = unselected.by_id(tmpid)) == NULL)
	  if((destcell = selected.by_id(tmpid)) == NULL)
	    destcell = addon.by_id(tmpid);
      }while((tmpid != id) || (k != i));
    }
    return connectcount;
}


int block::disconnectnodes(int i, listcell *pcell){

    int j, k, disconnectflag = NO;
    ID  destid, tmpid;
    block *destcell;

    if((exteriornode[i].cellid == id) &&
       (exteriornode[i].node == i)){ // this node is not connected
      return YES;
    }

    while(pcell != NULL){
      destcell = pcell->cellblk;
      if(destcell == this){
	pcell = pcell->next;
	continue;
      }

      destid = destcell->getid();
      if(connectednodes(i, destcell)){ // begin disconnect
	exteriornode[i].cellid = id;    // disconnected signiture
	k = j =  exteriornode[i].node;  // end point info in j
	exteriornode[i].node = i;       // disconnected signiture
	while(((tmpid = destcell->exteriornode[k].cellid) != id) ||
	       (destcell->exteriornode[k].node != i)){
	  k = destcell->exteriornode[k].node;
	  if((destcell = unselected.by_id(tmpid)) == NULL){
	    destcell = selected.by_id(tmpid);
	  }
	}
	destcell->exteriornode[k].cellid = destid;
	destcell->exteriornode[k].node = j;
	disconnectflag = YES;
      }
      if(disconnectflag == YES) break;
      pcell = pcell->next;
    }
    return disconnectflag;
}


int block::disconnectsides(int i, listcell *pcell){

    int j, k, disconnectflag = NO;
    ID  destid, tmpid;
    block *destcell;

    if((exteriorside[i].cellid == id) &&
      (exteriorside[i].side == i)){ // this side is not connected
      return YES;
    }

    while(pcell != NULL){
      destcell = pcell->cellblk;
      if(destcell == this){
	pcell = pcell->next;
	continue;
      }

      destid = destcell->getid();
      if(connectedsides(i, destcell)){ // begin disconnect
	exteriorside[i].cellid = id;    // disconnected signiture
	k = j =  exteriorside[i].side;  // end point info in j
	exteriorside[i].side = i;       // disconnected signiture
	while(((tmpid = destcell->exteriorside[k].cellid) != id) ||
	       (destcell->exteriorside[k].side != i)){
	  k = destcell->exteriorside[k].side;
	  if((destcell = unselected.by_id(tmpid)) == NULL){
	    destcell = selected.by_id(tmpid);
	  }
	}
	destcell->exteriorside[k].cellid = destid;
	destcell->exteriorside[k].side = j;
	disconnectflag = YES;
      }
      if(disconnectflag == YES) break;
      pcell = pcell->next;
    }
    return disconnectflag;
}



void block::move(double x, double y){

    xloc = x;
    yloc = y;
    snaptogrid();
    generatenodes();
}


void block::relmove(dPOINT reldisp){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -