电流流动效果实现
来源:互联网 发布:宝宝取名软件 编辑:程序博客网 时间:2024/04/30 09:21
前几天,到航天部实施项目,用户提出需求:希望电路分析后,能显示电路中电流流动效果。 回想起以前电力系统用户希望的电力接线图中潮流的需求,觉得这件事应该做一做了。
粗一想,不好做,但深入一想也容易解决,因此,花了一天时间,结果还令人满意。
大致应该分以下几步:
1. 设计处理对象及其成员与函数
2. 解决流动效果
3. 根据连接关系与分析结果确定各导线中电流方向
4. 联调
直观地想,电流流动效果应在导线中处理,在其每条线段中应知道如何画出效果。
首先,应由窗口进行调用或触发,演示时应有时钟。
加入TTimer *Timer_FlowEffect;
具体事务函数: void __fastcall ShowFlowEffect();
void __fastcall TCbwGraphBaseForm::ShowFlowEffect()
...{
Timer_FlowEffect->Enabled = !Timer_FlowEffect->Enabled;
FlushVector(FDemoLines, false);
if(Timer_FlowEffect->Enabled)
...{
GetBranchSimulateModule();
FBranchSimulateModule->DemoEffect(FDemoLines);
vector<TPin *> inPins, outPins;
CBW_ITERATOR(CbwObjects, FObjects)
...{
TWire * wire = dynamic_cast<TWire *>(*it);
if(wire)
wire->ShowDemoEffect(FDemoLines, inPins, outPins);
}
}
else
RefreshCurrentScreen();
}
...{
Timer_FlowEffect->Enabled = !Timer_FlowEffect->Enabled;
FlushVector(FDemoLines, false);
if(Timer_FlowEffect->Enabled)
...{
GetBranchSimulateModule();
FBranchSimulateModule->DemoEffect(FDemoLines);
vector<TPin *> inPins, outPins;
CBW_ITERATOR(CbwObjects, FObjects)
...{
TWire * wire = dynamic_cast<TWire *>(*it);
if(wire)
wire->ShowDemoEffect(FDemoLines, inPins, outPins);
}
}
else
RefreshCurrentScreen();
}
在Timer_FlowEffect的OnTimer事件中,进行动态显示效果展示而在导线类中加入演示效果处理函数:
void __fastcall TCbwGraphBaseForm::Timer_FlowEffectTimer(TObject *Sender)
...{
static int count = 0;
int deltaLength = 10;
if(++count >= deltaLength) count = 0;
TCbwBrushData * brushData = new TCbwBrushData;
brushData->BrushStyle = cbgtGradient;
brushData->MixStyle = true;
Gdiplus::Graphics graphics(PaintBox->Canvas->Handle, ' ');
CBW_ITERATOR(WireLines, FDemoLines)
...{
double w = (*it)->LineWidth;
if(w < 2) w = 2;
brushData->Color1 = (*it)->LineColor;
brushData->Color2 = 0xFFFFFF - brushData->Color1;
RECT r = (*it)->Border->Rect;
TRect clientRect = TRect(r.left, r.top, r.right, r.bottom);
TRect brushRect;
switch((*it)->WireDirection)
...{
case ctwdHorz:
brushData->BackgroundStyle = 0;
if((*it)->DemoDirection == clddForward)
brushRect = TRect(clientRect.left + count, clientRect.top, clientRect.left + count + deltaLength, clientRect.bottom);
else
brushRect = TRect(clientRect.right - count - deltaLength, clientRect.top, clientRect.right - count, clientRect.bottom);
break;
case ctwdVert:
brushData->BackgroundStyle = 1;
if((*it)->DemoDirection == clddForward)
brushRect = TRect(clientRect.left, clientRect.top + count, clientRect.right, clientRect.top + count + deltaLength);
else
brushRect = TRect(clientRect.left, clientRect.bottom - count - deltaLength, clientRect.right, clientRect.bottom - count);
break;
}
Gdiplus::Brush * brush1 = BrushByData(brushData, brushRect); //TRect(clientRect.left + count, clientRect.top, clientRect.left + count + deltaLength, clientRect.bottom);
graphics.FillRectangle(brush1,
int(clientRect.left),
int(clientRect.top),
int(clientRect.right - clientRect.left),
int(clientRect.bottom - clientRect.top));
delete brush1;
}
delete brushData;
}
...{
static int count = 0;
int deltaLength = 10;
if(++count >= deltaLength) count = 0;
TCbwBrushData * brushData = new TCbwBrushData;
brushData->BrushStyle = cbgtGradient;
brushData->MixStyle = true;
Gdiplus::Graphics graphics(PaintBox->Canvas->Handle, ' ');
CBW_ITERATOR(WireLines, FDemoLines)
...{
double w = (*it)->LineWidth;
if(w < 2) w = 2;
brushData->Color1 = (*it)->LineColor;
brushData->Color2 = 0xFFFFFF - brushData->Color1;
RECT r = (*it)->Border->Rect;
TRect clientRect = TRect(r.left, r.top, r.right, r.bottom);
TRect brushRect;
switch((*it)->WireDirection)
...{
case ctwdHorz:
brushData->BackgroundStyle = 0;
if((*it)->DemoDirection == clddForward)
brushRect = TRect(clientRect.left + count, clientRect.top, clientRect.left + count + deltaLength, clientRect.bottom);
else
brushRect = TRect(clientRect.right - count - deltaLength, clientRect.top, clientRect.right - count, clientRect.bottom);
break;
case ctwdVert:
brushData->BackgroundStyle = 1;
if((*it)->DemoDirection == clddForward)
brushRect = TRect(clientRect.left, clientRect.top + count, clientRect.right, clientRect.top + count + deltaLength);
else
brushRect = TRect(clientRect.left, clientRect.bottom - count - deltaLength, clientRect.right, clientRect.bottom - count);
break;
}
Gdiplus::Brush * brush1 = BrushByData(brushData, brushRect); //TRect(clientRect.left + count, clientRect.top, clientRect.left + count + deltaLength, clientRect.bottom);
graphics.FillRectangle(brush1,
int(clientRect.left),
int(clientRect.top),
int(clientRect.right - clientRect.left),
int(clientRect.bottom - clientRect.top));
delete brush1;
}
delete brushData;
}
void __fastcall TWire::ShowDemoEffect(WireLines& lines, vector<TPin *>& inPins, vector<TPin *>& outPins)
...{
vector<TPad *> allPads, inPads, outPads;
for(int i = 0; i < MetaNumber; ++i)
...{
CBW_MACRO_CAST(TPad, pad, Meta(i));
CBW_CONDITION_CONTINUE(!pad);
allPads.push_back(pad);
if(pad->Tag == 1)
inPads.push_back(pad);
if(pad->Tag == -1)
outPads.push_back(pad);
}
vector<TWireLine *> inLines;
while(inPads.size())
...{
TPad * pad = inPads[0];
vector<TWireLine *> allLines;
TWireLine * line = NULL; // 找到对应子导线
for(int i = 0; i < pad->ConnectedPointList->Count; ++i)
...{
TConnectPoint * cp = (TConnectPoint *)(pad->ConnectedPointList->Items[i]);
line = dynamic_cast<TWireLine *>(cp->ParentLine);
if(!line) continue;
if(AddItemToVector(inLines, line))
allLines.push_back(line);
else
line = NULL;
}
CBW_ITERATOR(vector<TWireLine *>, allLines)
...{
line = *it;
TPad * otherPad = line->BeginConnectPoint->Pad;
if(otherPad == pad) otherPad = line->EndConnectPoint->Pad;
bool reverseFlag = false;
if(line->WireDirection == ctwdHorz)
reverseFlag = (otherPad && otherPad->CentralPoint.x < pad->CentralPoint.x);
else
reverseFlag = (otherPad && otherPad->CentralPoint.y < pad->CentralPoint.y);
line->DemoDirection = reverseFlag;
if(otherPad)
...{
if(otherPad->Tag != -2)
lines.push_back(line);
if(otherPad->Tag == 0)
...{
otherPad->Tag = 1;
if(IndexOfItemInVector(inPads, otherPad) == -1)
inPads.push_back(otherPad);
}
}
}
inPads.erase(inPads.begin());
}
}
...{
vector<TPad *> allPads, inPads, outPads;
for(int i = 0; i < MetaNumber; ++i)
...{
CBW_MACRO_CAST(TPad, pad, Meta(i));
CBW_CONDITION_CONTINUE(!pad);
allPads.push_back(pad);
if(pad->Tag == 1)
inPads.push_back(pad);
if(pad->Tag == -1)
outPads.push_back(pad);
}
vector<TWireLine *> inLines;
while(inPads.size())
...{
TPad * pad = inPads[0];
vector<TWireLine *> allLines;
TWireLine * line = NULL; // 找到对应子导线
for(int i = 0; i < pad->ConnectedPointList->Count; ++i)
...{
TConnectPoint * cp = (TConnectPoint *)(pad->ConnectedPointList->Items[i]);
line = dynamic_cast<TWireLine *>(cp->ParentLine);
if(!line) continue;
if(AddItemToVector(inLines, line))
allLines.push_back(line);
else
line = NULL;
}
CBW_ITERATOR(vector<TWireLine *>, allLines)
...{
line = *it;
TPad * otherPad = line->BeginConnectPoint->Pad;
if(otherPad == pad) otherPad = line->EndConnectPoint->Pad;
bool reverseFlag = false;
if(line->WireDirection == ctwdHorz)
reverseFlag = (otherPad && otherPad->CentralPoint.x < pad->CentralPoint.x);
else
reverseFlag = (otherPad && otherPad->CentralPoint.y < pad->CentralPoint.y);
line->DemoDirection = reverseFlag;
if(otherPad)
...{
if(otherPad->Tag != -2)
lines.push_back(line);
if(otherPad->Tag == 0)
...{
otherPad->Tag = 1;
if(IndexOfItemInVector(inPads, otherPad) == -1)
inPads.push_back(otherPad);
}
}
}
inPads.erase(inPads.begin());
}
}
enum CbwLineDemoDirection
...{ // 导线演示方向
clddForward, // 前向: 左->右, 上->下
clddReverse, // 反向: 右->左, 下->上
clddNone // 无效果
};
...{ // 导线演示方向
clddForward, // 前向: 左->右, 上->下
clddReverse, // 反向: 右->左, 下->上
clddNone // 无效果
};
CbwLineDemoDirection FDemoDirection;
__property CbwLineDemoDirection DemoDirection = ...{ read = FDemoDirection, write = FDemoDirection};
__property CbwLineDemoDirection DemoDirection = ...{ read = FDemoDirection, write = FDemoDirection};
到目前为止,若简单地设置导线的各子导线对象的DemoDirection为true或false,运行,发现效果已出现。YEAH。
剩下的事就是根据连接关系确定电流的真正流向,以此确定各导线的子导线的DemoDirection,该项工作可由仿真模块完成,因其中已建立了电路的连接关系模型。加入DemoEffect处理函数即可。
void __fastcall TCbwBranchModule::DemoEffect(WireLines& lines)
...{
if(FSubModules.size())
CBW_ITERATOR(vector<TCbwBranchModule *>, FSubModules)
(*it)->DemoEffect(lines);
else
...{
vector<TPin *> inPins, outPins;
vector<TCbwNode *> inNodes, outNodes;
AllInOutPins(inPins, outPins, inNodes, outNodes);
CBW_ITERATOR(vector<TCbwSimulateBranch *>, FSimulateBranches)
(*it)->ForwardFlag = false;
CBW_ITERATOR(vector<TPin *>, inPins)
SetIOStatus(*it, 1);
vector<TCbwBranch *> foundBranches;
while(inNodes.size())
...{
TCbwNode * node = inNodes[0];
vector<TCbwBranch *> branchesToCheck;
CBW_ITERATOR(vector<TCbwSimulateBranch *>, FSimulateBranches)
...{
TCbwBranch * branch = (*it)->BranchByNode(node, inNodes);
if(!branch) continue;
if(IndexOfItemInVector(foundBranches, branch) != -1) continue;
foundBranches.push_back(branch);
branchesToCheck.push_back(branch);
}
CBW_ITERATOR(vector<TCbwBranch *>, branchesToCheck)
BranchWork(*it, inNodes);
inNodes.erase(inNodes.begin());
}
}
}
...{
if(FSubModules.size())
CBW_ITERATOR(vector<TCbwBranchModule *>, FSubModules)
(*it)->DemoEffect(lines);
else
...{
vector<TPin *> inPins, outPins;
vector<TCbwNode *> inNodes, outNodes;
AllInOutPins(inPins, outPins, inNodes, outNodes);
CBW_ITERATOR(vector<TCbwSimulateBranch *>, FSimulateBranches)
(*it)->ForwardFlag = false;
CBW_ITERATOR(vector<TPin *>, inPins)
SetIOStatus(*it, 1);
vector<TCbwBranch *> foundBranches;
while(inNodes.size())
...{
TCbwNode * node = inNodes[0];
vector<TCbwBranch *> branchesToCheck;
CBW_ITERATOR(vector<TCbwSimulateBranch *>, FSimulateBranches)
...{
TCbwBranch * branch = (*it)->BranchByNode(node, inNodes);
if(!branch) continue;
if(IndexOfItemInVector(foundBranches, branch) != -1) continue;
foundBranches.push_back(branch);
branchesToCheck.push_back(branch);
}
CBW_ITERATOR(vector<TCbwBranch *>, branchesToCheck)
BranchWork(*it, inNodes);
inNodes.erase(inNodes.begin());
}
}
}
对于仿真支路对象,则需要由节点返回其相应电路支路,设计一个函数。
TCbwBranch * __fastcall TCbwSimulateBranch::BranchByNode(TCbwNode * node, vector<TCbwNode *>& inNodes)
...{
TCbwNode * currentNode = FBeginNode;
if(IndexOfItemInVector(inNodes, currentNode) != -1)
FForwardFlag = true;
CBW_ITERATOR(TCbwBranches, FBranches)
...{
if(currentNode == node && FForwardFlag) return *it;
currentNode = (*it)->OtherNode(currentNode);
if(currentNode == node && !FForwardFlag) return *it;
}
return NULL;
}
...{
TCbwNode * currentNode = FBeginNode;
if(IndexOfItemInVector(inNodes, currentNode) != -1)
FForwardFlag = true;
CBW_ITERATOR(TCbwBranches, FBranches)
...{
if(currentNode == node && FForwardFlag) return *it;
currentNode = (*it)->OtherNode(currentNode);
if(currentNode == node && !FForwardFlag) return *it;
}
return NULL;
}
OK,现在再运行一把,万事OK,效果已达到预期。
可访问http://www.drgraph.com/download/flowDemo.swf查看效果
- 电流流动效果实现
- 图片流动效果实现(代码)
- WPF Path实现虚线流动效果
- Untiy Shader电流效果的实现。吼吼。。。
- unity 实现图片滚动效果(流动的水体)
- 基于HTML5实现3D监控应用流动效果
- 基于HTML5实现3D监控应用流动效果
- Labview使用自定义控件实现,管道内液体流动效果
- PCB中电流如何流动——电流如何沿传输线流动
- PCB中电流如何流动——差分电流如何流动
- AS3电流动画效果
- wp7电流效果
- 电子如何形成电流_不是流动而是振动
- 关于电阻为什么能阻碍电流流动(微观解释)
- 粒子系统制作流动效果
- [UnityShader3]边缘光流动效果
- HT for Web中3D流动效果的实现与应用
- windows api实现星空流动
- 电脑工程师和儿子的经对话
- 计算机三大理论基石
- 利用C#远程存取Access数据库
- 招聘之难
- 世界编程语言排行榜08年03月_Java 语言
- 电流流动效果实现
- 随便说说,标题想不出啥好的。
- 关于JAVA的一个小bug,拆分字符
- 使用WINSOCK加多线程写的一个下载模块(VB6.0)
- 关于应用程序和插件或DLL之间的关系
- 用Shell脚本实现自动从NewSmth.net的MyPhoto版下载照片
- 2008-3-21大盘分析
- 读我(Readme)
- getbulk数据量大时,必须设置Timeout