Skip to main content

中医学习程序

用 p5.js生成张仲景的《伤寒论》六经辨证的学习程序

这个 p5.js 程序具备的功能:

六经概述:介绍太阳、阳明、少阳、太阴、少阴、厥阴的特点。
症状与辨证:根据症状选择相应的经络,并显示诊断提示。
交互式学习:用户输入或点击选择病症,程序自动匹配相关条文或方剂。
方剂推荐:提供经典方剂,并显示组成和主治病机。
动态视觉效果:比如六经的能量流动图、穴位动画等。

下面提供一个 p5.js 的示例程序,通过一个简单的界面展示《伤寒论》中六经辨证的各经信息。当页面加载时,会在画布上以圆形排列六个“经络”按钮(太阳、少阳、阳明、太阴、少阴、厥阴);用户点击任一按钮后,就会显示该经的详细说明,并提供返回按钮回到总览界面。你可以将下面的代码复制到 p5.js 在线编辑器 中运行,体验交互效果。

let channels = []; let selectedChannel = null;

function setup() { createCanvas(800, 600); textAlign(CENTER, CENTER);

// 中心点和排列圆半径 let centerX = width / 2; let centerY = height / 2; let radiusCircle = 200; let angleIncrement = TWO_PI / 6;

// 定义各经名称和简介(说明内容可根据需要调整) let names = ["太阳经", "少阳经", "阳明经", "太阴经", "少阴经", "厥阴经"]; let descriptions = [ "太阳经:主要症状为发热、恶寒、头痛、身痛,适用于风寒表证。", "少阳经:症见寒热往来、胸胁苦满、口苦咽干,介于表里之间。", "阳明经:表现为高热、大汗出、口渴、便秘,病势偏热。", "太阴经:常伴腹满、呕吐、食欲不振、腹泻,偏寒湿内盛。", "少阴经:症状包括四肢冰冷、心悸、烦躁、厌食,偏向阴虚。", "厥阴经:病机复杂,表现为寒热交替、情绪波动、手足麻木。" ];

let angle = -PI / 2; // 从上方开始排列 for (let i = 0; i < 6; i++) { let x = centerX + radiusCircle * cos(angle); let y = centerY + radiusCircle * sin(angle); channels.push(new Channel(names[i], descriptions[i], x, y, 50)); angle += angleIncrement; } }

function draw() { background(240); if (selectedChannel == null) { // 绘制标题 textSize(24); fill(0); text("《伤寒论》六经辨证学习程序", width / 2, 50);

// 绘制各经按钮
for (let c of channels) {
  c.display();
}

// 绘制提示文字
textSize(16);
fill(50);
text("点击一个经络查看详细信息", width / 2, height - 30);

} else { // 显示选中经的详细信息 textSize(24); fill(0); text(selectedChannel.name, width / 2, 50); textSize(16); // 将详细说明显示在屏幕中间,可根据需要调整位置和格式 text(selectedChannel.description, width / 2, height / 2, width - 40, 200);

// 绘制返回按钮
rectMode(CENTER);
fill(200);
rect(width / 2, height - 50, 100, 40, 10);
fill(0);
text("返回", width / 2, height - 50);

} }

function mousePressed() { if (selectedChannel == null) { // 检测是否点击某个经络按钮 for (let c of channels) { if (c.isClicked(mouseX, mouseY)) { selectedChannel = c; break; } } } else { // 检测是否点击返回按钮 if ( mouseX > width / 2 - 50 && mouseX < width / 2 + 50 && mouseY > height - 70 && mouseY < height - 30 ) { selectedChannel = null; } } }

// 定义经络对象 class Channel { constructor(name, description, x, y, r) { this.name = name; this.description = description; this.x = x; this.y = y; this.r = r; }

display() { stroke(0); fill(200, 220, 255); ellipse(this.x, this.y, this.r * 2); fill(0); noStroke(); text(this.name, this.x, this.y); }

isClicked(mx, my) { let d = dist(mx, my, this.x, this.y); return d < this.r; } }

程序说明

总览界面
在 draw() 函数中,当没有选中任何经时,程序在画布上绘制了标题和六个以圆形排列的经络按钮,并在底部提示用户点击按钮查看详细信息。

详细信息显示
当用户点击某个经的按钮后,程序将该对象赋值给 selectedChannel,随后在界面中间显示该经的名称和详细描述,同时在底部绘制“返回”按钮以便返回总览。

交互检测
mousePressed() 函数负责检测用户点击,判断用户是点击了某个经络按钮还是“返回”按钮,从而更新状态。

《伤寒论》最核心的内容之一就是提出了“六经辨证”的概念,即太阳、阳明、少阳、太阴、少阴和厥阴六个阶段来分析疾病的发展过程。每个阶段都有其特定的症状表现和治疗方法。

《伤寒论》作为中医经典,其“六经辨证”思想在临床上具有极高的指导意义。该理论将外感疾病的发展过程分为六个阶段,每个阶段都有特定的症状表现和治疗方法,体现了对病情发展动态变化的深刻认识。下面是对六经辨证各阶段的简要说明:

太阳经
表现为外感初期的症状,如发热、恶寒、头痛、项背强痛等,通常属于风寒表证。治疗以疏散风寒、发汗解表为主,强调调和机体的正气与邪气的对抗。

少阳经
处于表里之间的过渡阶段,常见寒热往来、口苦、胸胁苦满等症状。这个阶段既有表证的特征,又开始出现里证的倾向,治疗上侧重于调和阴阳、疏肝理气,平衡体内的对抗状态。

阳明经
病势进入较为深里阶段,表现为高热、大汗、口渴、便秘等症状,显示热邪内炽。治疗主要是清热泻火、扶正祛邪,以恢复脏腑功能的正常运作。

太阴经
主要影响脾胃功能,常见症状包括胃寒呕吐、腹胀、腹泻等,显示出体内寒湿内盛。治疗上讲求温中散寒、健脾和胃,帮助恢复消化吸收功能。

少阴经
症状往往表现为心悸、四肢冰冷、烦躁、厌食等,反映出体内阴阳失衡,阴虚内热或阳气不足。治疗原则是温补或养阴清热,视具体情况而定。

厥阴经
病机最为复杂,往往出现寒热交替、情绪波动、手足麻木或抽搐等症状,显示出病邪深藏并难以调和。治疗上既需要平衡寒热,又须综合考虑调和全身阴阳,因人制宜。

这种辨证方法不仅揭示了病情从表及里的发展变化过程,也为临床上不同阶段的治疗提供了明确的指导思路。通过六经辨证,医师能够根据病人所处的具体阶段,采取相应的疏散、清热、温补或调和治疗,从而提高治疗的针对性和效果。

根据网络上相关资料(​、​)显示,六经辨证已成为中医治疗外感疾病的重要理论依据,并在后世不断得到发展和应用。

这种理论的核心在于“辨证论治”,即在了解病情发展的每个阶段特征的基础上,采取不同的治疗措施,从而实现因时制宜、因人而异的精准医疗。

下面给出一个基于 p5.js 的示例程序,展示《伤寒论》六经辨证核心内容的学习效果。程序在主界面中以圆形布局展示六个经络按钮(太阳、少阳、阳明、太阴、少阴、厥阴),点击其中任意按钮后,会显示该经的基本理论:包括阶段简介、主要症状及相应的治疗原则。你可以将下面的代码复制到 p5.js 在线编辑器 中运行并体验交互效果。

let channels = []; let selectedChannel = null;

function setup() { createCanvas(800, 600); textAlign(CENTER, CENTER);

// 定义画布中心及按钮排列圆半径 let centerX = width / 2; let centerY = height / 2; let radiusCircle = 200; let angleIncrement = TWO_PI / 6;

// 定义各经的名称、主要症状及治疗原则(核心内容) let names = ["太阳经", "少阳经", "阳明经", "太阴经", "少阴经", "厥阴经"]; let symptomsAndTreatment = [ "症状:发热、恶寒、头痛、项背强痛\n治疗:疏散风寒,发汗解表", "症状:寒热往来、口苦、胸胁苦满\n治疗:调和阴阳,疏肝理气", "症状:高热、大汗、口渴、便秘\n治疗:清热泻火,扶正祛邪", "症状:胃寒、呕吐、腹胀、腹泻\n治疗:温中散寒,健脾和胃", "症状:心悸、四肢冰冷、烦躁、厌食\n治疗:温补或养阴清热", "症状:寒热交替、情绪波动、手足麻木\n治疗:平衡阴阳,综合调理" ]; let descriptions = [ "太阳经为外感疾病初期,病邪多以风寒为主。", "少阳经处于表里之间,寒热往来是其典型表现。", "阳明经阶段病情加重,热邪内炽、津液耗损明显。", "太阴经主要影响脾胃,常见胃寒呕吐、腹泻等症。", "少阴经反映内在阴阳失衡,出现心悸、四肢冰冷等表现。", "厥阴经病情复杂,寒热交替,调治需综合平衡。" ];

let angle = -PI / 2; // 从上方开始排列 for (let i = 0; i < 6; i++) { let x = centerX + radiusCircle * cos(angle); let y = centerY + radiusCircle * sin(angle); channels.push(new Channel(names[i], symptomsAndTreatment[i], descriptions[i], x, y, 50)); angle += angleIncrement; } }

function draw() { background(240);

if (selectedChannel == null) { // 主界面:标题与六经按钮 textSize(24); fill(0); text("《伤寒论》六经辨证学习程序", width / 2, 50);

textSize(16);
text("点击任一经络查看详细内容", width / 2, height - 30);

// 绘制各经按钮
for (let channel of channels) {
  channel.display();
}

} else { // 详细信息显示界面 textSize(24); fill(0); text(selectedChannel.name, width / 2, 50);

// 显示阶段简介、症状与治疗原则
textSize(16);
fill(0);
text(selectedChannel.description, width / 2, 120, width - 40, 60);
text(selectedChannel.symptomsAndTreatment, width / 2, 200, width - 40, 100);

// 返回按钮
rectMode(CENTER);
fill(200);
rect(width / 2, height - 50, 100, 40, 10);
fill(0);
text("返回", width / 2, height - 50);

} }

function mousePressed() { if (selectedChannel == null) { // 检测是否点击某个经络按钮 for (let channel of channels) { if (channel.isClicked(mouseX, mouseY)) { selectedChannel = channel; break; } } } else { // 检测是否点击返回按钮 if ( mouseX > width / 2 - 50 && mouseX < width / 2 + 50 && mouseY > height - 70 && mouseY < height - 30 ) { selectedChannel = null; } } }

// 经络对象定义:包含名称、症状治疗信息、阶段简介、位置及半径 class Channel { constructor(name, symptomsAndTreatment, description, x, y, r) { this.name = name; this.symptomsAndTreatment = symptomsAndTreatment; this.description = description; this.x = x; this.y = y; this.r = r; }

display() { stroke(0); fill(180, 220, 255); ellipse(this.x, this.y, this.r * 2); fill(0); noStroke(); text(this.name, this.x, this.y); }

isClicked(mx, my) { return dist(mx, my, this.x, this.y) < this.r; } }

程序说明

主界面
程序在主界面上以圆形布局排列六个按钮,每个按钮代表《伤寒论》中的一个“经”。用户点击任一按钮,就进入详细学习界面。

详细界面
在详细界面中,程序显示所选经的名称、阶段简介以及对应的症状和治疗原则,帮助学习者快速掌握每个阶段的核心内容。

交互设计
用户可通过点击“返回”按钮返回主界面,程序简单直观,适合初学者了解和记忆六经辨证的基本理论。

这种交互方式能帮助学习者在视觉和操作上更直观地理解六经辨证的概念,结合文字说明强化记忆。

根据相关网络资料(​、​)的介绍,六经辨证不仅是对疾病发展阶段的划分,更为中医辨证论治提供了理论依据。你可以根据需要进一步扩展程序,比如加入动态动画、知识问答、方剂解析等功能,丰富学习体验。

用 p5.js生成张仲景的《伤寒论》“随证治之的原则”这个核心内容的学习程序。 张仲景强调“观其脉证,知犯何逆,随证治之”。意思是医生应当仔细观察患者的脉象和其他症状(证),以此判断病因并制定相应的治疗方案。这种方法重视个体化治疗,体现了中医整体观念。

下面提供一个基于 p5.js 的示例程序,模拟“随证治之”的学习过程,展示如何根据患者的脉象和症状(证)来做出个体化诊断和治疗建议。程序采用分步交互的方式:

主界面:显示程序标题及“开始诊断”按钮;
脉象观察:用户选择模拟的脉象(例如浮脉、沉脉、滑脉);
症状观察:用户选择患者的主要症状(如发热头痛、腹痛呕吐、四肢冰冷);
诊断结果:程序根据脉象与症状的组合,给出相应的治疗建议,体现“观其脉证,知犯何逆,随证治之”的原则。

你可以将下面的代码复制到 p5.js 在线编辑器 中运行、调试,并根据需要扩展或调整诊断逻辑和界面效果。

// 全局变量:当前状态、用户选择及模拟数据 let state = "main"; // 状态:"main"、"pulse"、"symptom"、"result" let selectedPulse = ""; let selectedSymptom = ""; let diagnosisText = "";

// 模拟的脉象选项,每个包含名称和简要说明 let pulses = [ { name: "浮脉", description: "表征风寒外感,常见于初期" }, { name: "沉脉", description: "反映寒湿内盛,多见于里证" }, { name: "滑脉", description: "常见于痰饮或热症,质滑有力" } ];

// 模拟的症状选项,每个包含名称和简要说明 let symptoms = [ { name: "发热头痛", description: "外感风寒引起,头痛明显" }, { name: "腹痛呕吐", description: "内寒湿邪入里,胃肠不适" }, { name: "四肢冰冷", description: "阳虚寒凝,血气运行不畅" } ];

function setup() { createCanvas(800, 600); textAlign(CENTER, CENTER); }

function draw() { background(240);

if (state === "main") { displayMain(); } else if (state === "pulse") { displayPulseSelection(); } else if (state === "symptom") { displaySymptomSelection(); } else if (state === "result") { displayResult(); } }

// 主界面显示程序标题和“开始诊断”按钮 function displayMain() { textSize(28); fill(0); text("《伤寒论》随证治之学习程序", width/2, 100);

textSize(20); fill(50); text("点击下方按钮开始诊断", width/2, 200);

// 开始诊断按钮 drawButton(width/2 - 75, 300, 150, 50, "开始诊断"); }

// 脉象选择界面 function displayPulseSelection() { textSize(24); fill(0); text("请选择脉象观察结果", width/2, 80);

// 按钮排列 let startY = 150; let gap = 100; for (let i = 0; i < pulses.length; i++) { let btnX = width/2 - 75; let btnY = startY + i * gap; drawButton(btnX, btnY, 150, 50, pulses[i].name); // 显示脉象描述 textSize(14); fill(80); text(pulses[i].description, width/2, btnY + 35); }

// 返回按钮,返回主界面 drawButton(20, 20, 80, 40, "返回"); }

// 症状选择界面 function displaySymptomSelection() { textSize(24); fill(0); text("请选择患者症状", width/2, 80);

let startY = 150; let gap = 100; for (let i = 0; i < symptoms.length; i++) { let btnX = width/2 - 75; let btnY = startY + i * gap; drawButton(btnX, btnY, 150, 50, symptoms[i].name); // 显示症状描述 textSize(14); fill(80); text(symptoms[i].description, width/2, btnY + 35); }

// 返回按钮,返回脉象选择界面 drawButton(20, 20, 80, 40, "返回"); }

// 结果显示界面:展示用户选择及系统诊断(治疗建议) function displayResult() { textSize(24); fill(0); text("诊断结果", width/2, 80);

textSize(20); fill(0); text("脉象: " + selectedPulse, width/2, 150); text("症状: " + selectedSymptom, width/2, 200);

textSize(18); fill(50); textWrap(WORD); text(diagnosisText, width/2, 300, width - 100);

// 重新诊断按钮 drawButton(width/2 - 75, height - 80, 150, 50, "重新诊断"); }

// 通用按钮绘制函数 function drawButton(x, y, w, h, label) { rectMode(CORNER); fill(200); stroke(0); rect(x, y, w, h, 10);

fill(0); noStroke(); textSize(18); text(label, x + w/2, y + h/2); }

// 事件处理:检测鼠标点击各个区域对应的按钮 function mousePressed() { if (state === "main") { if (isInsideButton(width/2 - 75, 300, 150, 50, mouseX, mouseY)) { state = "pulse"; } } else if (state === "pulse") { // 检测脉象按钮点击 for (let i = 0; i < pulses.length; i++) { let btnX = width/2 - 75; let btnY = 150 + i * 100; if (isInsideButton(btnX, btnY, 150, 50, mouseX, mouseY)) { selectedPulse = pulses[i].name; state = "symptom"; return; } } // 返回按钮 if (isInsideButton(20, 20, 80, 40, mouseX, mouseY)) { state = "main"; } } else if (state === "symptom") { // 检测症状按钮点击 for (let i = 0; i < symptoms.length; i++) { let btnX = width/2 - 75; let btnY = 150 + i * 100; if (isInsideButton(btnX, btnY, 150, 50, mouseX, mouseY)) { selectedSymptom = symptoms[i].name; diagnosisText = getDiagnosis(selectedPulse, selectedSymptom); state = "result"; return; } } // 返回按钮 if (isInsideButton(20, 20, 80, 40, mouseX, mouseY)) { state = "pulse"; } } else if (state === "result") { // 检测重新诊断按钮 if (isInsideButton(width/2 - 75, height - 80, 150, 50, mouseX, mouseY)) { selectedPulse = ""; selectedSymptom = ""; diagnosisText = ""; state = "main"; } } }

// 辅助函数:判断鼠标是否点击在按钮区域内 function isInsideButton(x, y, w, h, mx, my) { return mx >= x && mx <= x + w && my >= y && my <= y + h; }

// 根据脉象和症状组合,给出相应的治疗建议(模拟诊断逻辑) function getDiagnosis(pulse, symptom) { if (pulse === "浮脉" && symptom === "发热头痛") { return "治法:辛温解表,祛风散寒,适用于太阳表证。"; } else if (pulse === "沉脉" && symptom === "腹痛呕吐") { return "治法:温中散寒,健脾理气,适用于太阴内证。"; } else if (pulse === "滑脉" && symptom === "四肢冰冷") { return "治法:养阴清热,补阳益气,适用于少阴证。"; } else { return "治法:根据具体证候辨证论治,因人而异。"; } }

程序说明

分步交互
程序采用状态机逻辑,由“main”(主界面)→“pulse”(脉象观察)→“symptom”(症状观察)→“result”(诊断结果)构成,模拟医生观察脉象和症状后进行辨证施治的过程。

个体化诊断
根据用户选择的脉象和症状组合,程序调用 getDiagnosis() 函数返回相应的治疗建议,体现了“观其脉证,知犯何逆,随证治之”的核心思想。

扩展性
你可以根据需要增加更多的脉象和症状选项,或者加入动画、图像等元素,进一步丰富程序的交互性和表现力。

这种教学程序有助于理解张仲景在《伤寒论》中所强调的个体化辨证论治思想,也体现了中医整体观念的应用。根据网络资料(​)介绍,此类交互式学习工具正逐渐被应用于中医教育中,为学习者提供更直观的临床思维训练。

用 p5.js生成张仲景的《伤寒论》“方剂与用药原则”这个核心内容的学习程序。

书中记载了许多经典的方剂,如桂枝汤、麻黄汤等,并详细说明了每种方剂的组成成分及其适应症。此外,《伤寒论》还特别强调了药物配伍的重要性,例如“君臣佐使”的配伍原则,确保了治疗的安全性和有效性。

下面提供一个 p5.js 示例程序,模拟《伤寒论》中关于“方剂与用药原则”的学习过程。程序分为两个主要部分:

经典方剂:展示书中记载的经典方剂(如桂枝汤、麻黄汤),点击后显示每个方剂的组成成分、适应症,并说明其遵循“君臣佐使”配伍原则。
药物配伍原则:单独介绍“君臣佐使”的核心思想,解释各类药物在方剂中的作用与意义,体现中医整体观念与个体化治疗。

你可以将下面的代码复制到 p5.js 在线编辑器 中运行和调试。

// 状态变量控制程序界面 // 状态: "main" 主界面;"formulaList" 经典方剂列表;"formulaDetail" 具体方剂详情;"principle" 药物配伍原则 let state = "main"; let formulas = []; let selectedFormula = null;

function setup() { createCanvas(800, 600); textAlign(CENTER, CENTER); // 定义经典方剂(可根据需要扩展更多) formulas = [ { name: "桂枝汤", ingredients: "桂枝、芍药、生姜、大枣、甘草", indications: "适用于风寒表证,患者常有发热、恶寒、无汗等症状。" }, { name: "麻黄汤", ingredients: "麻黄、杏仁、桂枝、甘草", indications: "适用于外感风寒、无汗证,常见于表证加重的情况。" } ]; }

function draw() { background(240);

if (state === "main") { drawMain(); } else if (state === "formulaList") { drawFormulaList(); } else if (state === "formulaDetail") { drawFormulaDetail(); } else if (state === "principle") { drawPrinciple(); } }

// 主界面:提供两个选项 function drawMain() { textSize(28); fill(0); text("《伤寒论》方剂与用药原则学习程序", width / 2, 100);

// 两个选项按钮 drawButton(width / 2 - 100, 250, 200, 50, "经典方剂"); drawButton(width / 2 - 100, 350, 200, 50, "药物配伍原则"); }

// 经典方剂列表界面 function drawFormulaList() { textSize(26); fill(0); text("请选择一个经典方剂", width / 2, 80);

let startY = 150; let gap = 100; for (let i = 0; i < formulas.length; i++) { drawButton(width / 2 - 100, startY + i * gap, 200, 50, formulas[i].name); }

// 返回主界面按钮 drawButton(20, 20, 80, 40, "返回"); }

// 具体方剂详情界面 function drawFormulaDetail() { textSize(28); fill(0); text(selectedFormula.name, width / 2, 80);

textSize(20); fill(0); text("组成成分: " + selectedFormula.ingredients, width / 2, 180); text("适应症: " + selectedFormula.indications, width / 2, 240);

textSize(18); fill(50); textWrap(WORD); text( "该方剂遵循“君臣佐使”的配伍原则:君药主导治病,臣药辅佐增强疗效,佐药调和药性,使药引经入脉,整体配伍确保治疗安全有效。", width / 2, 320, width - 100, 150 );

// 返回上一级按钮 drawButton(20, 20, 80, 40, "返回"); }

// 药物配伍原则说明界面 function drawPrinciple() { textSize(28); fill(0); text("药物配伍原则", width / 2, 80);

textSize(20); fill(0); textWrap(WORD); let principleText = "《伤寒论》强调方剂中药物必须按照“君臣佐使”的配伍原则进行组合:\n\n" + "【君药】—— 主药,对症治病;\n" + "【臣药】—— 辅助君药,增强疗效;\n" + "【佐药】—— 协调诸药,减轻毒副作用;\n" + "【使药】—— 引导药效,调和全方。\n\n" + "这种配伍方法确保了治疗的针对性、安全性和整体调节作用,体现了中医辨证论治的精髓。"; text(principleText, width / 2, 160, width - 100, 400);

// 返回主界面按钮 drawButton(20, 20, 80, 40, "返回"); }

// 鼠标点击事件处理 function mousePressed() { if (state === "main") { // 进入经典方剂列表 if (isInsideButton(width / 2 - 100, 250, 200, 50, mouseX, mouseY)) { state = "formulaList"; } // 进入药物配伍原则说明 else if (isInsideButton(width / 2 - 100, 350, 200, 50, mouseX, mouseY)) { state = "principle"; } } else if (state === "formulaList") { // 检查返回按钮 if (isInsideButton(20, 20, 80, 40, mouseX, mouseY)) { state = "main"; return; } // 检查每个方剂按钮 let startY = 150; let gap = 100; for (let i = 0; i < formulas.length; i++) { if (isInsideButton(width / 2 - 100, startY + i * gap, 200, 50, mouseX, mouseY)) { selectedFormula = formulas[i]; state = "formulaDetail"; break; } } } else if (state === "formulaDetail") { // 返回经典方剂列表 if (isInsideButton(20, 20, 80, 40, mouseX, mouseY)) { state = "formulaList"; } } else if (state === "principle") { // 返回主界面 if (isInsideButton(20, 20, 80, 40, mouseX, mouseY)) { state = "main"; } } }

// 通用按钮绘制函数 function drawButton(x, y, w, h, label) { rectMode(CORNER); fill(200); stroke(0); rect(x, y, w, h, 10);

fill(0); noStroke(); textSize(18); text(label, x + w / 2, y + h / 2); }

// 辅助函数:判断鼠标是否在按钮区域内 function isInsideButton(x, y, w, h, mx, my) { return mx >= x && mx <= x + w && my >= y && my <= y + h; }

程序说明

主界面
显示程序标题,并提供两个入口按钮:
    经典方剂:进入方剂列表,用户可以选择具体方剂查看详细信息。
    药物配伍原则:直接展示《伤寒论》中“君臣佐使”的配伍原则及其意义。

经典方剂列表与详情
在方剂列表界面,用户可点击“桂枝汤”或“麻黄汤”按钮进入详情界面。详情中不仅展示方剂的组成成分和适应症,还特别说明了该方剂如何遵循“君臣佐使”的配伍原则,保证治疗的安全有效。

药物配伍原则说明
独立页面详细介绍“君臣佐使”原则,解释每个角色(君、臣、佐、使)的作用,帮助学习者理解中医辨证论治中的核心思维。

这种交互式程序能帮助学习者直观理解《伤寒论》中关于方剂与用药的理论,并通过视觉与操作的方式记忆各个关键概念。根据需要,你可以进一步扩展更多方剂及详细的临床案例分析。

用 p5.js生成张仲景的《伤寒论》“病机十九条”这个核心内容的学习程序。 严格来说,“病机十九条”出自《素问·至真要大论》,但《伤寒论》也继承和发展了这一思想,用以解释不同病症背后的病理变化规律。这有助于更好地理解疾病的本质,并指导临床实践。

下面提供一个 p5.js 示例程序,通过交互式界面学习《伤寒论》继承和发展的“病机十九条”思想。程序包含三个界面:

主界面:介绍学习程序和“病机十九条”的基本理念,并提供“开始学习”按钮。
列表界面:以网格形式展示 19 个病机条目,每个条目代表一种病理变化机制。
详情界面:点击任一条目后,显示该病机条目的名称和详细说明,同时提供返回按钮,便于反复学习。

你可以将以下代码复制到 p5.js 在线编辑器 中运行和调试。请根据需要调整各条目的名称和内容,下面的内容为示例说明。

// 全局状态变量 // state:"main" 主界面;"list" 列表界面;"detail" 详情界面 let state = "main";

// 病机十九条数据,每个对象包含 name 和 detail let mechanisms = [ { name: "条目1:正气不足", detail: "正气不足,机体正气虚弱,抵抗力下降,是疾病发生的重要内因。" }, { name: "条目2:邪气入侵", detail: "外邪入侵使人体正气受损,引发多种病理变化,体现外因与内因的交互作用。" }, { name: "条目3:表里不和", detail: "表里不和反映病邪由表及里的转变,影响全身经络运行,常导致病情加重。" }, { name: "条目4:阴阳失调", detail: "阴阳失调是中医病机的核心,说明机体阴阳平衡被打破,导致各种病症。" }, { name: "条目5:寒热错杂", detail: "寒热错杂指体内寒热两种病理因素同时存在,体现病情复杂多变的特点。" }, { name: "条目6:气血亏虚", detail: "气血亏虚使得脏腑功能失常,体虚无力,是多种慢性病的重要机理。" }, { name: "条目7:脏腑失调", detail: "脏腑功能失调反映内脏器官之间协调失衡,直接影响全身健康状态。" }, { name: "条目8:气机阻滞", detail: "气机阻滞则表现为气血运行不畅,常引起局部疼痛和功能障碍。" }, { name: "条目9:血液淤阻", detail: "血液淤阻是由于气滞引起的血流不畅,可导致局部循环障碍和疼痛。" }, { name: "条目10:津液失调", detail: "津液失调说明体内水液代谢异常,常见于痰湿、浮肿等症状。" }, { name: "条目11:营卫不和", detail: "营卫不和描述营血与卫气失去平衡,易导致感冒、发热等外感病症。" }, { name: "条目12:脉络不通", detail: "脉络不通体现为全身经脉运行受阻,常见于风湿、疼痛等疾病。" }, { name: "条目13:痰湿内生", detail: "痰湿内生是由于脾胃虚弱、运化失常导致体内痰湿聚集,引发多种病机变化。" }, { name: "条目14:风邪上扰", detail: "风邪上扰说明外界风邪侵袭上焦,引起头痛、眩晕等症状。" }, { name: "条目15:火热内蕴", detail: "火热内蕴指体内因感染或情志不遂等原因导致热邪内盛,出现高热、烦躁等表现。" }, { name: "条目16:湿热内蒸", detail: "湿热内蒸是湿与热相互作用,导致内环境异常,常见于痤疮、湿疹等皮肤问题。" }, { name: "条目17:气阴两虚", detail: "气阴两虚体现为气虚和阴虚同时存在,机体功能全面减退,易引起全身性虚弱。" }, { name: "条目18:肝气郁结", detail: "肝气郁结反映情志失调引起的气机不畅,可导致胸闷、抑郁等症状。" }, { name: "条目19:脾胃虚弱", detail: "脾胃虚弱说明消化吸收功能低下,容易引起食欲不振、疲劳等慢性病症。" } ];

let selectedMechanism = null; // 当前选中的病机条目

// 主界面:显示程序标题和开始学习按钮 function drawMain() { background(240); textAlign(CENTER, CENTER); textSize(28); fill(0); text("《伤寒论》病机十九条学习程序", width/2, 100);

textSize(20); fill(50); text("认识病机,洞察病理变化", width/2, 150);

// 开始学习按钮 drawButton(width/2 - 75, 300, 150, 50, "开始学习"); }

// 列表界面:以网格形式展示 19 个条目 function drawList() { background(240); textAlign(CENTER, CENTER); textSize(24); fill(0); text("点击病机条目查看详细内容", width/2, 40);

// 设定网格参数:4 行 × 5 列(最多20个格子),这里只显示19个条目 let cols = 5; let rows = 4; let marginX = 50; let marginY = 80; let gridWidth = width - marginX * 2; let gridHeight = height - marginY - 50; let cellW = gridWidth / cols; let cellH = gridHeight / rows;

for (let i = 0; i < mechanisms.length; i++) { let col = i % cols; let row = floor(i / cols); let x = marginX + col * cellW; let y = marginY + row * cellH;

// 绘制单元格按钮
drawButton(x + 10, y + 10, cellW - 20, cellH - 20, mechanisms[i].name);

}

// 返回按钮 drawButton(20, 20, 80, 40, "返回"); }

// 详情界面:显示选中条目的详细信息 function drawDetail() { background(240); textAlign(CENTER, TOP); textSize(26); fill(0); text(selectedMechanism.name, width/2, 60);

textSize(18); fill(50); textWrap(WORD); text(selectedMechanism.detail, width/2, 120, width - 100);

// 返回列表按钮 drawButton(20, 20, 80, 40, "返回"); }

// p5.js 主绘制循环,根据 state 调用不同界面绘制函数 function draw() { if (state === "main") { drawMain(); } else if (state === "list") { drawList(); } else if (state === "detail") { drawDetail(); } }

// 通用按钮绘制函数 function drawButton(x, y, w, h, label) { rectMode(CORNER); fill(200); stroke(0); rect(x, y, w, h, 10);

fill(0); noStroke(); textSize(16); text(label, x + w/2, y + h/2); }

// 鼠标点击事件处理,根据当前界面判断点击效果 function mousePressed() { if (state === "main") { // 检查“开始学习”按钮 if (isInsideButton(width/2 - 75, 300, 150, 50, mouseX, mouseY)) { state = "list"; } } else if (state === "list") { // 检查返回按钮 if (isInsideButton(20, 20, 80, 40, mouseX, mouseY)) { state = "main"; return; } // 检查各网格按钮 let cols = 5; let marginX = 50; let marginY = 80; let gridWidth = width - marginX * 2; let gridHeight = height - marginY - 50; let cellW = gridWidth / cols; let cellH = gridHeight / 4;

// 遍历所有病机条目,判断点击位置
for (let i = 0; i < mechanisms.length; i++) {
  let col = i % cols;
  let row = floor(i / cols);
  let x = marginX + col * cellW + 10;
  let y = marginY + row * cellH + 10;
  if (isInsideButton(x, y, cellW - 20, cellH - 20, mouseX, mouseY)) {
    selectedMechanism = mechanisms[i];
    state = "detail";
    break;
  }
}

} else if (state === "detail") { // 详情界面返回按钮 if (isInsideButton(20, 20, 80, 40, mouseX, mouseY)) { state = "list"; } } }

// 辅助函数:判断鼠标是否在按钮区域内 function isInsideButton(x, y, w, h, mx, my) { return mx >= x && mx <= x + w && my >= y && my <= y + h; }

程序说明

主界面
显示程序标题及“认识病机,洞察病理变化”的提示,并提供“开始学习”按钮,点击后进入病机条目列表。

列表界面
程序以网格方式排列 19 个病机条目(示例中采用 5 列 4 行的网格布局),每个按钮上显示条目名称,点击任一按钮进入该条目的详细说明页面。

详情界面
显示选中病机条目的名称和详细解释,帮助学习者了解不同病理机制背后的理论。右上角的“返回”按钮可返回列表页面。

这种交互式程序旨在帮助学习者通过逐项了解“病机十九条”的核心内容,加深对疾病病理变化规律的认识,并为临床实践提供理论指导。

根据相关中医文献和网络资料(​)介绍,这种基于条目式学习的方式有助于构建系统性的病机知识体系。

用 p5.js生成张仲景的《伤寒论》“调整阴阳平衡”这个核心内容的学习程序。

根据郑钦安的观点,“于阴阳上探求至理”,意味着学习《伤寒论》时应将阴阳理论放在首位。书中多次提到如何通过调节人体内部阴阳失衡来达到治愈疾病的目的。

下面给出一个 p5.js 示例程序,模拟“调整阴阳平衡”的学习过程,突出“于阴阳上探求至理”的理念。程序主要特点包括:

交互式调整:通过两个滑块分别调整“阴”与“阳”的数值,模拟人体内部阴阳状态;
直观反馈:根据阴阳数值的差异,程序实时绘制一个阴阳图形,并显示“阴阳平衡”或“阴阳失衡”的状态;
视觉效果:阴阳图形会根据滑块调整自动旋转,形象地反映平衡与否的变化。

你可以将下面代码复制到 p5.js 在线编辑器 中运行和调试:

let yinSlider, yangSlider; let resetButton; let d = 200; // 阴阳图直径

function setup() { createCanvas(800, 600); angleMode(RADIANS); textAlign(CENTER, CENTER);

// 创建阴阳滑块,初始值50(平衡状态),范围0~100 yinSlider = createSlider(0, 100, 50); yinSlider.position(150, height - 60); yinSlider.style('width', '200px');

yangSlider = createSlider(0, 100, 50); yangSlider.position(width - 350, height - 60); yangSlider.style('width', '200px');

// 重置按钮:将阴阳恢复平衡 resetButton = createButton("重置平衡"); resetButton.position(width/2 - 40, height - 100); resetButton.mousePressed(resetSliders); }

function draw() { background(240);

// 获取滑块当前值 let yinVal = yinSlider.value(); let yangVal = yangSlider.value();

// 计算两者差值,映射为旋转角度(-PI/6~PI/6) let diff = yangVal - yinVal; let rotationAngle = map(diff, -100, 100, -PI/6, PI/6);

// 显示标题和说明 textSize(28); fill(0); text("《伤寒论》—— 调整阴阳平衡", width/2, 40);

textSize(18); text("于阴阳上探求至理:调节阴阳失衡以达治愈之道", width/2, 80);

// 绘制阴阳图形(根据阴阳平衡情况旋转) push(); translate(width/2, height/2); rotate(rotationAngle); drawYinYang(d); pop();

// 显示滑块标签及当前数值 textSize(16); fill(0); text("阴:" + yinVal, 250, height - 80); text("阳:" + yangVal, width - 250, height - 80);

// 判断平衡状态(允许误差在±3以内视为平衡) let status = (abs(yinVal - yangVal) <= 3) ? "阴阳平衡" : "阴阳失衡"; fill(0); textSize(24); text(status, width/2, height - 30); }

// 绘制标准阴阳图形 function drawYinYang(diameter) { noStroke(); // 绘制上下两半:上半黑、下半白 fill(0); arc(0, 0, diameter, diameter, -HALF_PI, HALF_PI, PIE); fill(255); arc(0, 0, diameter, diameter, HALF_PI, 3*HALF_PI, PIE);

// 绘制上半内的小白圆 fill(255); ellipse(0, -diameter/4, diameter/2, diameter/2);

// 绘制下半内的小黑圆 fill(0); ellipse(0, diameter/4, diameter/2, diameter/2);

// 在小圆中绘制点:上部黑点、下部白点 fill(0); ellipse(0, diameter/4, diameter/8, diameter/8); fill(255); ellipse(0, -diameter/4, diameter/8, diameter/8); }

// 重置函数:将阴阳滑块恢复到50 function resetSliders() { yinSlider.value(50); yangSlider.value(50); }

程序说明

交互式调整
两个滑块分别代表人体内的“阴”与“阳”状态,初始值均为 50,代表平衡。用户可以通过拖动滑块调整数值。

阴阳图形绘制
程序采用 arc() 与 ellipse() 函数绘制经典阴阳图形,并根据“阳”与“阴”的数值差异计算一个旋转角度。平衡时图形不旋转,若失衡则会自动倾斜,直观反映内在状态的变化。

状态反馈
当阴阳数值误差在 ±3 范围内时,程序判定为“阴阳平衡”;否则显示“阴阳失衡”。同时提供“重置平衡”按钮,便于用户快速恢复平衡状态。

这种交互式学习程序能够帮助学习者直观理解《伤寒论》中调节阴阳平衡的核心思想,贯彻郑钦安“于阴阳上探求至理”的理念,从而更好地把握中医理论在治病中的实践意义。

用 p5.js生成张仲景的《伤寒论》“脉法与诊断技术”这个核心内容的学习程序。

《伤寒论》不仅讲述了具体的病症处理方法,还涉及到了脉诊及其他诊断技巧的应用。例如,“浮脉宜以汗解”,就是根据脉象特点决定治疗策略的一个例子。

下面提供一个 p5.js 示例程序,通过交互式界面学习《伤寒论》中关于脉法与诊断技术的核心内容。程序分为三个主要界面:

主界面
显示程序标题和简介,用户点击“开始诊断”进入脉象选择界面。

脉象选择界面
程序提供多个脉象选项(如浮脉、沉脉、迟脉、滑脉、弦脉),用户点击相应脉象后,系统会依据中医诊断原理给出对应的治疗建议(例如“浮脉宜以汗解”)。

诊断结果界面
显示所选脉象及对应的治疗建议,同时提供返回按钮,便于重新选择。

你可以将以下代码复制到 p5.js 在线编辑器 中运行、调试,并根据需要扩展或修改脉象及诊断内容。

// 程序状态变量: // "main":主界面;"pulse":脉象选择界面;"result":诊断结果界面 let state = "main"; let selectedPulse = null; let pulses = [];

function setup() { createCanvas(800, 600); textAlign(CENTER, CENTER);

// 定义脉象及其对应的治疗建议(示例内容,可根据需要调整) pulses = [ { name: "浮脉", treatment: "浮脉宜以汗解:病邪停留于表,宜采取发汗解表的方法疏散风寒。" }, { name: "沉脉", treatment: "沉脉反映寒邪内盛:宜以温中散寒调理脾胃,增强正气。" }, { name: "迟脉", treatment: "迟脉多见于阳虚体质:宜采用温补之法,振奋阳气,增强体能。" }, { name: "滑脉", treatment: "滑脉常见于痰湿内盛:宜以化痰利湿、清热化浊的方法治疗。" }, { name: "弦脉", treatment: "弦脉多因肝气郁结:宜以疏肝解郁,调整气机,缓解症状。" } ]; }

function draw() { background(240);

if (state === "main") { drawMain(); } else if (state === "pulse") { drawPulseSelection(); } else if (state === "result") { drawResult(); } }

// 主界面:显示程序标题、简介及“开始诊断”按钮 function drawMain() { textSize(28); fill(0); text("《伤寒论》脉法与诊断技术学习程序", width / 2, 100);

textSize(18); fill(50); text("根据脉象决定治疗策略:例如“浮脉宜以汗解”", width / 2, 150);

// “开始诊断”按钮 drawButton(width / 2 - 75, 300, 150, 50, "开始诊断"); }

// 脉象选择界面:展示多个脉象选项 function drawPulseSelection() { textSize(24); fill(0); text("请选择脉象", width / 2, 50);

let startY = 120; let gap = 70; for (let i = 0; i < pulses.length; i++) { drawButton(width / 2 - 75, startY + i * gap, 150, 50, pulses[i].name); }

// 返回按钮,返回主界面 drawButton(20, 20, 80, 40, "返回"); }

// 诊断结果界面:显示选中的脉象及对应的治疗建议 function drawResult() { textSize(24); fill(0); text("诊断结果", width / 2, 50);

textSize(20); fill(0); text("脉象:" + selectedPulse.name, width / 2, 120);

text("治疗建议:", width / 2, 160); textSize(18); fill(50); textWrap(WORD); text(selectedPulse.treatment, width / 2, 200, width - 100);

// 返回按钮,返回脉象选择界面 drawButton(20, 20, 80, 40, "返回"); }

// 鼠标点击事件处理,根据当前状态判断点击效果 function mousePressed() { if (state === "main") { if (isInsideButton(width / 2 - 75, 300, 150, 50, mouseX, mouseY)) { state = "pulse"; } } else if (state === "pulse") { // 检测返回按钮 if (isInsideButton(20, 20, 80, 40, mouseX, mouseY)) { state = "main"; return; } // 检测每个脉象按钮 let startY = 120; let gap = 70; for (let i = 0; i < pulses.length; i++) { if (isInsideButton(width / 2 - 75, startY + i * gap, 150, 50, mouseX, mouseY)) { selectedPulse = pulses[i]; state = "result"; break; } } } else if (state === "result") { // 检测返回按钮 if (isInsideButton(20, 20, 80, 40, mouseX, mouseY)) { state = "pulse"; } } }

// 通用按钮绘制函数 function drawButton(x, y, w, h, label) { rectMode(CORNER); fill(200); stroke(0); rect(x, y, w, h, 10);

fill(0); noStroke(); textSize(18); text(label, x + w / 2, y + h / 2); }

// 辅助函数:判断鼠标是否在按钮区域内 function isInsideButton(x, y, w, h, mx, my) { return mx >= x && mx <= x + w && my >= y && my <= y + h; }

程序说明

主界面
显示程序标题和说明,突出《伤寒论》中脉法与诊断技术的重要性,并提供“开始诊断”按钮进入下一步。

脉象选择界面
用户可选择不同的脉象(如浮脉、沉脉、迟脉、滑脉、弦脉),每个脉象对应一种诊断思路。示例中“浮脉”对应“浮脉宜以汗解”,即根据脉象特点决定治疗策略。

诊断结果界面
显示用户所选脉象及系统给出的治疗建议,帮助学习者理解如何依据脉诊结果制定相应的治疗方案,同时提供返回按钮便于反复学习。

这种交互式程序能直观展示《伤寒论》中脉诊及诊断技术的应用,帮助学习者体会中医辨证论治中“观脉辨证”的精髓。

整合以上的功能,用 p5.js生成张仲景的《伤寒论》的学习程序

下面提供一个整合了多模块功能的 p5.js 示例程序,涵盖《伤寒论》的多个核心内容学习模块,包括:

六经辨证:以圆形布局展示六个经络,点击后查看各经的基本特点和治疗思路;
脉诊与诊断技术:选择脉象(如浮脉、沉脉等),系统给出相应的治疗建议(例如“浮脉宜以汗解”);
方剂与用药原则:展示经典方剂(如桂枝汤、麻黄汤),点击后查看组成、适应症及“君臣佐使”配伍说明;
病机十九条:以网格形式展示 19 个病机条目,点击后可查看详细解释;
调整阴阳平衡:通过两个滑块调整“阴”与“阳”的数值,实时绘制阴阳图形,并显示平衡状态。

你可以将下面的代码复制到 p5.js 在线编辑器 中运行、调试,并根据需要进一步扩展和调整各模块内容。

// 全局状态变量: // "main" 主菜单; // "sixChannels" 六经辨证; // "pulseDiagnosis" 脉诊与诊断技术; // "formulas" 方剂与用药原则; // "pathogenesis" 病机十九条; // "yinYang" 调整阴阳平衡 let state = "main";

// ---------------------- // 数据定义 // ----------------------

// 六经辨证数据(示例数据) let sixChannels = []; let selectedChannel = null;

// 脉诊数据(示例数据) let pulseDiagnosisData = []; let selectedPulse = null;

// 方剂数据(示例数据) let formulas = []; let selectedFormula = null;

// 病机十九条数据(示例数据) let mechanisms = []; let selectedMechanism = null;

// 阴阳模块使用的 DOM 元素 let yinSlider, yangSlider, resetButton;

// ---------------------- // 初始化数据 // ---------------------- function initSixChannels() { let names = ["太阳经", "少阳经", "阳明经", "太阴经", "少阴经", "厥阴经"]; let details = [ "太阳经:外感初期,以风寒为主。治疗主张疏散风寒、发汗解表。", "少阳经:表里之间,寒热往来。治疗讲究调和阴阳、疏肝理气。", "阳明经:热邪内炽,表现高热、大汗。宜清热泻火、扶正祛邪。", "太阴经:脾胃失调,胃寒呕吐、腹泻。主张温中散寒、健脾和胃。", "少阴经:阴阳失衡,心悸、四肢冰冷。治疗以温补或养阴清热为主。", "厥阴经:寒热错杂,调治需综合平衡阴阳。" ]; for (let i = 0; i < names.length; i++) { sixChannels.push({ name: names[i], detail: details[i] }); } }

function initPulseDiagnosis() { pulseDiagnosisData = [ { name: "浮脉", treatment: "浮脉宜以汗解:病邪停留于表,宜采取发汗解表的方法疏散风寒。" }, { name: "沉脉", treatment: "沉脉反映寒邪内盛:宜以温中散寒调理脾胃,增强正气。" }, { name: "迟脉", treatment: "迟脉多见于阳虚体质:宜采用温补之法,振奋阳气。" }, { name: "滑脉", treatment: "滑脉常见于痰湿内盛:宜以化痰利湿、清热化浊的方法治疗。" }, { name: "弦脉", treatment: "弦脉多因肝气郁结:宜以疏肝解郁,调整气机,缓解症状。" } ]; }

function initFormulas() { formulas = [ { name: "桂枝汤", ingredients: "桂枝、芍药、生姜、大枣、甘草", indications: "适用于风寒表证,发热、恶寒、无汗等症状。" }, { name: "麻黄汤", ingredients: "麻黄、杏仁、桂枝、甘草", indications: "适用于外感风寒、无汗证,症见表证加重。" } ]; }

function initMechanisms() { mechanisms = [ { name: "1. 正气不足", detail: "正气不足,机体防御能力下降,是疾病发生的重要内因。" }, { name: "2. 邪气入侵", detail: "外邪入侵使人体正气受损,致使病邪乘虚而入。" }, { name: "3. 表里不和", detail: "表里失调反映病邪由表及里、转化发展的过程。" }, { name: "4. 阴阳失调", detail: "阴阳失衡是中医病机的核心,机体失去平衡则易生病。" }, { name: "5. 寒热错杂", detail: "体内寒热两种病理因素同时存在,病情复杂多变。" }, { name: "6. 气血亏虚", detail: "气血不足使脏腑功能紊乱,常见于慢性病患者。" }, { name: "7. 脏腑失调", detail: "内脏器官之间协调失衡,直接影响全身健康。" }, { name: "8. 气机阻滞", detail: "气血运行不畅,易导致局部疼痛及功能障碍。" }, { name: "9. 血液淤阻", detail: "血液循环不畅,常引起局部淤血、疼痛等症状。" }, { name: "10. 津液失调", detail: "体内水液代谢异常,可导致痰湿、浮肿等表现。" }, { name: "11. 营卫不和", detail: "营卫失调易引发外感病症,如感冒、发热等。" }, { name: "12. 脉络不通", detail: "经脉运行受阻,往往表现为风湿、疼痛等临床症状。" }, { name: "13. 痰湿内生", detail: "脾胃运化失常导致痰湿聚集,影响全身机能。" }, { name: "14. 风邪上扰", detail: "风邪侵袭上焦,引起头痛、眩晕等症状。" }, { name: "15. 火热内蕴", detail: "体内热邪内盛,常伴高热、烦躁等表现。" }, { name: "16. 湿热内蒸", detail: "湿与热相互作用,导致内环境异常,皮肤问题多见。" }, { name: "17. 气阴两虚", detail: "气虚和阴虚并存,机体功能全面减退,易感疲劳。" }, { name: "18. 肝气郁结", detail: "情志不畅导致肝气郁结,表现为胸闷、抑郁等症状。" }, { name: "19. 脾胃虚弱", detail: "脾胃功能低下,消化吸收障碍,常伴食欲不振、疲倦。" } ]; }

// ---------------------- // p5.js setup 与 draw // ---------------------- function setup() { createCanvas(800, 600); textAlign(CENTER, CENTER);

// 初始化各模块数据 initSixChannels(); initPulseDiagnosis(); initFormulas(); initMechanisms();

// 创建阴阳模块的滑块和按钮,初始时隐藏 yinSlider = createSlider(0, 100, 50); yinSlider.position(150, height - 60); yinSlider.style('width', '200px'); yinSlider.hide();

yangSlider = createSlider(0, 100, 50); yangSlider.position(width - 350, height - 60); yangSlider.style('width', '200px'); yangSlider.hide();

resetButton = createButton("重置平衡"); resetButton.position(width / 2 - 40, height - 100); resetButton.mousePressed(resetYinYang); resetButton.hide(); }

function draw() { background(240); updateDOMVisibility();

if (state === "main") { drawMainMenu(); } else if (state === "sixChannels") { drawSixChannels(); } else if (state === "pulseDiagnosis") { drawPulseDiagnosis(); } else if (state === "formulas") { drawFormulas(); } else if (state === "pathogenesis") { drawPathogenesis(); } else if (state === "yinYang") { drawYinYang(); } }

// 根据当前状态控制 DOM 元素的显示或隐藏 function updateDOMVisibility() { if (state === "yinYang") { yinSlider.show(); yangSlider.show(); resetButton.show(); } else { yinSlider.hide(); yangSlider.hide(); resetButton.hide(); } }

// ---------------------- // 主菜单界面 // ---------------------- function drawMainMenu() { textSize(28); fill(0); text("《伤寒论》学习程序", width / 2, 60);

textSize(20); fill(50); text("请选择一个学习模块", width / 2, 100);

// 主菜单按钮 drawButton(width / 2 - 100, 150, 200, 50, "六经辨证"); drawButton(width / 2 - 100, 220, 200, 50, "脉诊与诊断"); drawButton(width / 2 - 100, 290, 200, 50, "方剂与用药"); drawButton(width / 2 - 100, 360, 200, 50, "病机十九条"); drawButton(width / 2 - 100, 430, 200, 50, "调整阴阳平衡"); }

// ---------------------- // 模块1:六经辨证 // ---------------------- function drawSixChannels() { // 如果未选择具体经,显示总览 if (selectedChannel === null) { textSize(26); fill(0); text("【六经辨证】", width / 2, 40); textSize(18); text("点击任一经查看详细说明", width / 2, 70);

// 以圆形排列六个经络按钮
let centerX = width / 2;
let centerY = height / 2;
let radiusCircle = 200;
let angleIncrement = TWO_PI / sixChannels.length;
let angle = -PI / 2;
for (let i = 0; i < sixChannels.length; i++) {
  let x = centerX + radiusCircle * cos(angle);
  let y = centerY + radiusCircle * sin(angle);
  // 绘制按钮
  fill(180, 220, 255);
  stroke(0);
  ellipse(x, y, 80, 80);
  fill(0);
  noStroke();
  text(sixChannels[i].name, x, y);
  angle += angleIncrement;
}
// 返回主菜单按钮
drawButton(20, 20, 80, 40, "返回");

} else { // 详细说明界面 textSize(26); fill(0); text(selectedChannel.name, width / 2, 60); textSize(18); fill(50); textWrap(WORD); text(selectedChannel.detail, width / 2, 120, width - 100); drawButton(20, 20, 80, 40, "返回"); } }

// ---------------------- // 模块2:脉诊与诊断技术 // ---------------------- function drawPulseDiagnosis() { if (selectedPulse === null) { textSize(24); fill(0); text("请选择脉象", width / 2, 40); let startY = 100; let gap = 70; for (let i = 0; i < pulseDiagnosisData.length; i++) { drawButton(width / 2 - 75, startY + i * gap, 150, 50, pulseDiagnosisData[i].name); } drawButton(20, 20, 80, 40, "返回"); } else { textSize(24); fill(0); text("诊断结果", width / 2, 40); textSize(20); text("脉象:" + selectedPulse.name, width / 2, 100); textSize(18); fill(50); textWrap(WORD); text(selectedPulse.treatment, width / 2, 140, width - 100); drawButton(20, 20, 80, 40, "返回"); } }

// ---------------------- // 模块3:方剂与用药原则 // ---------------------- function drawFormulas() { if (selectedFormula === null) { textSize(26); fill(0); text("请选择一个经典方剂", width / 2, 40); let startY = 100; let gap = 80; for (let i = 0; i < formulas.length; i++) { drawButton(width / 2 - 100, startY + i * gap, 200, 50, formulas[i].name); } drawButton(20, 20, 80, 40, "返回"); } else { textSize(26); fill(0); text(selectedFormula.name, width / 2, 60); textSize(20); fill(0); text("组成成分: " + selectedFormula.ingredients, width / 2, 140); text("适应症: " + selectedFormula.indications, width / 2, 180); textSize(18); fill(50); textWrap(WORD); text("该方剂遵循“君臣佐使”的配伍原则,君药主治,臣药辅佐,佐药协调,令药引经入脉,确保治疗安全有效。", width / 2, 240, width - 100); drawButton(20, 20, 80, 40, "返回"); } }

// ---------------------- // 模块4:病机十九条 // ---------------------- function drawPathogenesis() { if (selectedMechanism === null) { textSize(24); fill(0); text("点击病机条目查看详细内容", width / 2, 30);

// 网格排列 19 个条目(示例采用 5 列,4 行,最后一格留空)
let cols = 5;
let rows = 4;
let marginX = 50;
let marginY = 60;
let gridWidth = width - marginX * 2;
let gridHeight = height - marginY - 50;
let cellW = gridWidth / cols;
let cellH = gridHeight / rows;
for (let i = 0; i < mechanisms.length; i++) {
  let col = i % cols;
  let row = floor(i / cols);
  let x = marginX + col * cellW + 10;
  let y = marginY + row * cellH + 10;
  drawButton(x, y, cellW - 20, cellH - 20, mechanisms[i].name);
}
drawButton(20, 20, 80, 40, "返回");

} else { textSize(26); fill(0); text(selectedMechanism.name, width / 2, 60); textSize(18); fill(50); textWrap(WORD); text(selectedMechanism.detail, width / 2, 120, width - 100); drawButton(20, 20, 80, 40, "返回"); } }

// ---------------------- // 模块5:调整阴阳平衡 // ---------------------- function drawYinYang() { textSize(28); fill(0); text("调整阴阳平衡", width / 2, 40); textSize(18); fill(50); text("于阴阳上探求至理:调节阴阳失衡以达治愈之道", width / 2, 80);

// 绘制阴阳图形,依据滑块数值调整旋转角度 let yinVal = yinSlider.value(); let yangVal = yangSlider.value(); let diff = yangVal - yinVal; let rotationAngle = map(diff, -100, 100, -PI/6, PI/6);

push(); translate(width / 2, height / 2); rotate(rotationAngle); drawYinYangSymbol(200); pop();

textSize(16); fill(0); text("阴:" + yinVal, 250, height - 80); text("阳:" + yangVal, width - 250, height - 80);

let status = (abs(yinVal - yangVal) <= 3) ? "阴阳平衡" : "阴阳失衡"; textSize(24); fill(0); text(status, width / 2, height - 30);

drawButton(20, 20, 80, 40, "返回"); }

// 绘制阴阳图形函数 function drawYinYangSymbol(diameter) { noStroke(); // 上半部分(黑色) fill(0); arc(0, 0, diameter, diameter, -HALF_PI, HALF_PI, PIE); // 下半部分(白色) fill(255); arc(0, 0, diameter, diameter, HALF_PI, 3 * HALF_PI, PIE); // 上半内小圆(白色) fill(255); ellipse(0, -diameter / 4, diameter / 2, diameter / 2); // 下半内小圆(黑色) fill(0); ellipse(0, diameter / 4, diameter / 2, diameter / 2); // 小圆中的点 fill(0); ellipse(0, diameter / 4, diameter / 8, diameter / 8); fill(255); ellipse(0, -diameter / 4, diameter / 8, diameter / 8); }

// ---------------------- // 公共辅助函数:绘制按钮、判断鼠标在按钮内 // ---------------------- function drawButton(x, y, w, h, label) { rectMode(CORNER); fill(200); stroke(0); rect(x, y, w, h, 10);

fill(0); noStroke(); textSize(18); text(label, x + w / 2, y + h / 2); }

function isInsideButton(x, y, w, h, mx, my) { return mx >= x && mx <= x + w && my >= y && my <= y + h; }

// ---------------------- // 重置阴阳平衡滑块 // ---------------------- function resetYinYang() { yinSlider.value(50); yangSlider.value(50); }

// ---------------------- // 全局鼠标点击事件,根据当前状态处理 // ---------------------- function mousePressed() { // 全局“返回”按钮:若点击左上角【返回】,返回主菜单或上一级 if (isInsideButton(20, 20, 80, 40, mouseX, mouseY)) { if (state === "main") { // 主菜单无返回动作 } else if (state === "sixChannels") { if (selectedChannel !== null) { selectedChannel = null; } else { state = "main"; } } else if (state === "pulseDiagnosis") { if (selectedPulse !== null) { selectedPulse = null; } else { state = "main"; } } else if (state === "formulas") { if (selectedFormula !== null) { selectedFormula = null; } else { state = "main"; } } else if (state === "pathogenesis") { if (selectedMechanism !== null) { selectedMechanism = null; } else { state = "main"; } } else if (state === "yinYang") { state = "main"; } return; }

// 主菜单点击检测 if (state === "main") { if (isInsideButton(width / 2 - 100, 150, 200, 50, mouseX, mouseY)) { state = "sixChannels"; selectedChannel = null; } else if (isInsideButton(width / 2 - 100, 220, 200, 50, mouseX, mouseY)) { state = "pulseDiagnosis"; selectedPulse = null; } else if (isInsideButton(width / 2 - 100, 290, 200, 50, mouseX, mouseY)) { state = "formulas"; selectedFormula = null; } else if (isInsideButton(width / 2 - 100, 360, 200, 50, mouseX, mouseY)) { state = "pathogenesis"; selectedMechanism = null; } else if (isInsideButton(width / 2 - 100, 430, 200, 50, mouseX, mouseY)) { state = "yinYang"; } }

// 六经辨证:若未选中具体经,则检测各圆形按钮 if (state === "sixChannels" && selectedChannel === null) { let centerX = width / 2; let centerY = height / 2; let radiusCircle = 200; let angleIncrement = TWO_PI / sixChannels.length; let angle = -PI / 2; for (let i = 0; i < sixChannels.length; i++) { let x = centerX + radiusCircle * cos(angle); let y = centerY + radiusCircle * sin(angle); if (dist(mouseX, mouseY, x, y) < 40) { selectedChannel = sixChannels[i]; break; } angle += angleIncrement; } }

// 脉诊与诊断模块:检测脉象按钮 if (state === "pulseDiagnosis" && selectedPulse === null) { let startY = 100; let gap = 70; for (let i = 0; i < pulseDiagnosisData.length; i++) { if (isInsideButton(width / 2 - 75, startY + i * gap, 150, 50, mouseX, mouseY)) { selectedPulse = pulseDiagnosisData[i]; break; } } }

// 方剂模块:检测每个方剂按钮 if (state === "formulas" && selectedFormula === null) { let startY = 100; let gap = 80; for (let i = 0; i < formulas.length; i++) { if (isInsideButton(width / 2 - 100, startY + i * gap, 200, 50, mouseX, mouseY)) { selectedFormula = formulas[i]; break; } } }

// 病机十九条模块:检测网格中每个条目 if (state === "pathogenesis" && selectedMechanism === null) { let cols = 5; let marginX = 50; let marginY = 60; let gridWidth = width - marginX * 2; let gridHeight = height - marginY - 50; let cellW = gridWidth / cols; let cellH = gridHeight / 4; for (let i = 0; i < mechanisms.length; i++) { let col = i % cols; let row = floor(i / cols); let x = marginX + col * cellW + 10; let y = marginY + row * cellH + 10; if (isInsideButton(x, y, cellW - 20, cellH - 20, mouseX, mouseY)) { selectedMechanism = mechanisms[i]; break; } } } }

程序说明

主菜单
程序启动后显示《伤寒论》学习程序的主菜单,提供 5 个学习模块入口按钮。

六经辨证模块
以圆形布局展示 6 个经络(太阳、少阳、阳明、太阴、少阴、厥阴),点击某一经后显示详细说明;点击【返回】按钮返回主菜单或列表视图。

脉诊与诊断模块
用户选择不同的脉象(浮脉、沉脉、迟脉、滑脉、弦脉),系统根据选择给出对应治疗建议,体现“观其脉证,知犯何逆,随证治之”。

方剂与用药原则模块
展示经典方剂列表(例如桂枝汤、麻黄汤),点击后显示组成、适应症及“君臣佐使”配伍原则说明。

病机十九条模块
以网格形式排列 19 个病机条目,点击后显示每条目详细说明,帮助理解疾病病理变化规律。

调整阴阳平衡模块
通过两个滑块调整阴阳数值,并根据数值差异实时绘制经典阴阳图形,直观反馈“阴阳平衡”或“阴阳失衡”的状态,同时提供重置按钮。

每个模块均内置【返回】按钮,方便用户在各模块之间自由切换。你可以根据需要进一步扩展数据内容和交互效果,深入学习《伤寒论》的精髓。

下面对代码的整体结构和各部分功能进行详细解释,帮助你理解这份整合版《伤寒论》学习程序的实现原理。

  1. 全局变量与数据结构

    状态变量 state 用于记录当前显示的模块或页面,可能的取值有: "main":主菜单界面; "sixChannels":六经辨证模块; "pulseDiagnosis":脉诊与诊断技术模块; "formulas":方剂与用药原则模块; "pathogenesis":病机十九条模块; "yinYang":调整阴阳平衡模块。

    各模块数据数组 用于存储每个模块显示所需的文字和内容,例如: sixChannels:存储六经辨证的名称和详细说明; pulseDiagnosisData:存储脉诊中不同脉象及其对应的治疗建议; formulas:存储经典方剂的信息,包括组成成分、适应症等; mechanisms:存储病机十九条各条目的名称与详细解释; 每个模块还用一个变量(例如 selectedChannel、selectedPulse 等)保存当前选中的条目,用于显示详情。

    阴阳平衡模块使用的 DOM 元素 创建了两个滑块(yinSlider、yangSlider)和一个重置按钮(resetButton),用于动态调整阴阳值和重置状态。它们在非“yinYang”状态下会被隐藏。

  2. 初始化函数

在代码中有多个初始化函数,分别对不同模块的数据进行填充:

initSixChannels()
定义了六经辨证的名称和对应的详细说明,将数据存入 sixChannels 数组中。

initPulseDiagnosis()
定义了脉诊模块中各脉象(如浮脉、沉脉、迟脉等)和相应的治疗建议,存入 pulseDiagnosisData 数组。

initFormulas()
定义了经典方剂的信息,如“桂枝汤”和“麻黄汤”,包括组成成分和适应症说明,存入 formulas 数组。

initMechanisms()
将“病机十九条”的各条目(示例中使用了19个条目)以名称和详细解释存入 mechanisms 数组。

这些初始化函数在 setup() 函数中调用,以确保程序启动时各模块数据已经就绪。 3. p5.js 的 setup() 函数

在 setup() 中主要完成以下工作:

创建画布与文本对齐
使用 createCanvas(800, 600) 建立 800×600 的绘图区,设置文本居中对齐。

初始化各模块数据
分别调用前面提到的 initSixChannels()、initPulseDiagnosis()、initFormulas() 和 initMechanisms()。

创建阴阳平衡模块的 DOM 元素
创建两个滑块和一个重置按钮,并设置它们的位置、宽度,随后默认调用 .hide() 隐藏这些元素,只有在进入 “yinYang” 状态时才显示。
  1. p5.js 的 draw() 函数与页面切换

    状态控制 每次绘制时,通过判断全局变量 state 的值来调用对应模块的绘制函数。例如: state === "main" 时调用 drawMainMenu() 绘制主菜单; state === "sixChannels" 调用 drawSixChannels() 绘制六经辨证模块; …依此类推。

    DOM 显示控制 函数 updateDOMVisibility() 用于根据当前状态决定是否显示阴阳模块的滑块和按钮。当 state 为 "yinYang" 时,这些 DOM 元素显示,否则隐藏。

  2. 各模块详细绘制函数 5.1 主菜单模块:drawMainMenu()

    显示标题(“《伤寒论》学习程序”)和提示文字(“请选择一个学习模块”)。 通过调用 drawButton() 绘制五个按钮,每个按钮对应一个模块: “六经辨证” “脉诊与诊断” “方剂与用药” “病机十九条” “调整阴阳平衡”

5.2 六经辨证模块:drawSixChannels()

总览状态:当 selectedChannel 为 null 时,
    在屏幕中部以圆形布局排列六个经络按钮(利用三角函数 cos 和 sin 计算每个按钮的位置)。
    每个按钮用 ellipse() 绘制,显示经络名称。
    同时在左上角绘制返回按钮。
详情状态:如果用户已点击某个经(即 selectedChannel 不为空),则显示该经的详细说明文本,并提供返回按钮返回列表状态。

5.3 脉诊与诊断模块:drawPulseDiagnosis()

如果 selectedPulse 为 null,显示脉象选择界面:
    列出各个脉象按钮(浮脉、沉脉、迟脉等),每个按钮通过 drawButton() 绘制。
    提供返回按钮,点击返回主菜单。
如果已经选择了脉象,则进入结果显示界面:
    显示所选脉象名称及其对应的治疗建议文本。

5.4 方剂与用药原则模块:drawFormulas()

类似于脉诊模块:
    如果 selectedFormula 为 null,显示方剂列表(例如桂枝汤、麻黄汤)。
    用户点击某个方剂后,显示该方剂的组成、适应症及对“君臣佐使”配伍原则的说明。
    同样包含返回按钮。

5.5 病机十九条模块:drawPathogenesis()

若未选中具体条目(selectedMechanism 为 null),以网格布局方式排列 19 个条目按钮。
    网格参数(列数、行数、边距等)由变量计算确定,每个条目用 drawButton() 绘制。
若选中某个条目,则显示该病机条目的详细说明,并提供返回按钮。

5.6 调整阴阳平衡模块:drawYinYang()

显示模块标题和说明文字,解释“于阴阳上探求至理”这一理念。
从两个滑块中获取阴(yinSlider.value())和阳(yangSlider.value())的数值。
根据两者的差值计算旋转角度(使用 map() 函数将差值映射到一个角度范围,如 -PI/6 到 PI/6)。
利用 push()、translate() 和 rotate() 进行坐标变换,然后调用 drawYinYangSymbol() 绘制经典阴阳图形。
同时显示当前阴阳数值和判断状态(若差值在 ±3 范围内,则显示“阴阳平衡”,否则显示“阴阳失衡”)。
最后绘制一个返回按钮。
  1. 辅助函数

    drawButton(x, y, w, h, label) 封装了绘制按钮的操作:先用 rect() 绘制带圆角的矩形,再在按钮中央用 text() 写上标签。

    isInsideButton(x, y, w, h, mx, my) 判断鼠标点击的位置是否落在指定按钮区域内,返回布尔值,用于点击检测。

    drawYinYangSymbol(diameter) 绘制阴阳图形: 使用 arc() 绘制黑白两半圆; 在上下各画一个小圆,再在小圆中画出对比色的小点,构成经典的阴阳图形。

    resetYinYang() 当点击“重置平衡”按钮时,将阴阳滑块数值重置为 50,恢复平衡状态。

  2. 事件处理:mousePressed()

在 mousePressed() 中,根据当前状态和鼠标点击位置进行处理:

全局返回按钮
检查左上角“返回”按钮(区域固定为 (20,20) 到 (20+80,20+40)),如果点击返回,则根据当前状态决定返回主菜单或上一级页面。例如:
    在详细界面中返回列表;
    在列表界面中返回主菜单。
主菜单点击
判断点击位置是否落在主菜单中的各个模块按钮区域,若是则更新 state 到对应模块,并重置相应选中的数据变量(例如 selectedChannel 等)。
各模块内的点击检测
    在六经辨证模块中,如果 selectedChannel 为 null,则检测圆形按钮是否被点击,利用 dist() 函数计算鼠标与各按钮中心的距离。
    在脉诊、方剂、病机模块中,遍历各个按钮区域,利用 isInsideButton() 函数检测点击位置,并更新对应的选中变量。

每个分支的点击处理后,会更新全局状态变量和选中对象,从而在下一次 draw() 循环中呈现出相应的界面。 总结

这份整合代码通过全局状态控制、多模块数据组织和统一的按钮点击处理,实现了一个包含多个中医学习模块的交互式程序。每个模块:

都有自己的数据(如六经辨证、脉诊、方剂、病机、阴阳平衡),
采用不同的布局(圆形排列、列表、网格、动态图形)展示内容,
并提供返回与交互机制让用户能自由切换各模块,从而整体呈现《伤寒论》中的核心内容和诊疗思想。

这种结构既展示了 p5.js 强大的图形与交互功能,也体现了中医理论教学中“整体观”、“辨证论治”的思路。