📄 gridsub2.c
字号:
/*
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 + -