目录
基于Java3D的网络三维技术的设计与实现 1
摘要: 1
Abstract: 1
第一章 绪论 5
§1.1 引言 5
§1.2 互联网3D图形技术的应用 5
§1.3 JAVA3D在Web中的成功 6
第二章 Java3D技术的简介 7
§2.1 Java3D概述 7
2.1.1 Java3D简介 7
2.1.2 Java3D与其他三维技术的比较 7
§2.2 Java3D的场景图结构 9
2.2.1 虚拟宇宙(Virtual Universe) 10
2.2.2 Java3D的坐标系统 10
2.2.3 场景(Locale) 12
§2.3 实现三维世界 13
2.3.1 Java3D的观察模式 13
2.3.2 Java3D中用来定义观察的对象 14
2.3.3 在三维世界中建立、移动观察点 16
2.3.4 Java3D的网络基础 17
第三章 实现JAVA3D结构体系的方法 17
§3.1 总体设计 17
§3.2 基本形体的生成 17
3.2.1平板的生成 17
3.2.2 立方体的生成 18
3.2.3 圆锥的生成 18
3.2.4 球体的生成 18
3.2.5.圆柱体的生成 19
§3.3 点、线、面的生成 19
3.3.1点的生成 19
3.3.2直线的生成 20
3.3.3面的生成 20
§3.4 外部复杂形体的调用 21
§3.5背景变换的实现方法 21
3.5.1 灯光 21
3.5.2 纹理贴图 23
3.5.3 雾 23
§3.6 动画的生成 23
第四章JAVA3D场景的实现 24
§4.1Java3D的实现流程 24
§4.2 JAVA3D的建模 25
4.2.1 生成场景: 25
4.2.2 Temple的圆柱体的构建 25
4.2.3 Tower的构建 26
§4.3 动画的实现 28
4.3.1 调用galleon.obj文件 28
4.3.2 物体转动 29
4.3.3场景的移动 29
§4.4 背景变换 31
4.4.1 创建灯光 31
4.4.2 创建背景图片 34
4.4.3 指数雾 35
4.4.4 背景音乐 36
§4.5 在网页上显示3D图形 37
第五章 实践和展望 39
§5.1 Web3D技术发展前景 39
§5.2 论文总结 40
参考文献 40
第三章 实现JAVA3D结构体系的方法
§3.1 总体设计
设计思想是:以JAVA3D为平台,使用JBuilder编译器,生成一个三维小场景,实现简单实体建模,物体运动,场景移动,各种灯光,雾等场景变换操作以及更换背景图片增加背景音乐等三维体系的基本功能。
§3.2 基本形体的生成
和VRML不同,JAVA3D没有基本形体类,因而在程序中无法直接生成大量应用的基本形体,如BOX、CONE、SPHERE等。我们可以通过复杂的编程生成这些基本形体,也可以直接调用JAVA3D为我们提供的geometry classes,利用它生成程序所需要的BOX、COLORCUBE、CONE、SPHERE、CYLINDER。下面是这些基本体的生成方法。
3.2.1平板的生成
UTILITY里BOX的构造函数有:
1.Box():成一个各边尺寸均为2的BOX,要说明的是,BOX、COLORCUBE、SPHERE的坐标原点均在其中心点,CONE、CYLINDER的则在其轴线的中点上。
2.Box(float xdim, float ydim, Appearance ap) :成一个给定尺寸、给定外观属性的BOX ,例Box(.5f, .6f, .4f, myApp)
3.Box(float xdim, float ydim, float zdim, int primflags, Appearance ap):生成一个有特定说明的BOX,例如:Box(.4f,.6f,.3f,Primitive.ENABLE_APPEARANCE_MODIFY, ap)表示程序在运行时可以改变其外观属性。
3.2.2 立方体的生成
UTILITY里COLORCUBE的构造函数有:
1.ColorCube()
生成一个边长均为2的COLORCUBE
1.ColorCube(double scale)
将边长均为2的COLORCUBE按比例放大缩小。
3.2.3 圆锥的生成
UTILITY里CONE的构造函数有:
1.public Cone()
生成一个底半径为1,高为2的CONE。
2.Cone (float radius, float height)
3.Cone (float radius, float height, int primflags, Appearance ap)
4.Cone(float radius, float height, int primflags, int xdivision, int ydivision, Appearance ap)
这里,xdivision、ydivision可用来表示圆锥的显示是高精度的显示,或是底精度的显示,缺省时的中等精度时xdivision = 15; ydivision = 1; 我们可利用这两个参数来改变显示的效果,使显示圆锥的三角片更多或更少些。
3.2.4 球体的生成
UTILITY里SPHERE的构造函数有:
1.Sphere()
生成一个半径为1的SPHERE。
2.Sphere (float radius)
3.Sphere (float radius, Appearance ap)
4.Sphere(float radius, int primflags, Appearance ap)
5.Sphere(float radius, int primflags, int divisions)
6.Sphere(float radius, int primflags, int divisions, Appearance ap)
这里,divisions的作用和圆锥的xdivision、ydivision相似。
3.2.5.圆柱体的生成
UTILITY里CYLINDER的构造函数有:
1.Cylinder()
生成一个底半径为1,高为2的CYLINDER。
2.Cylinder (float radius, float height)
3.Cylinder (float radius, float height, Appearance ap)
4. Cylinder (float radius, float height, int primflags, Appearance ap)
5. Cylinder(float radius, float height, int primflags, int xdivision, int ydivision, Appearance ap)
§3.3 点、线、面的生成
3.3.1点的生成
编写JAVA3D程序实际上是编写一个特定的场景图,给出了场景图中带有形体及其属性的一个分支(BranchGroup)和表示观察位置等数据的另一个分支(View Platform)。一般来说,表示观测位置的分支可以用JAVA3D的UTILITY来完成,即createSceneGraph方法的定义。
在这个方法里,程序先定义了一个分支objRoot,然后用数组的形式定义了顶点坐标vert和颜色color,再用PointArray 定义了一组点point,并将顶点坐标及颜色赋值给point,由于JAVA3D中的PointArray点是Shape3D的子类,它不能直接放入一个BranchGroup,因而我们还要先定义一个Shape3D对象shape,再将point赋予shape,这样point就可以放入BranchGroup类型的对象objRoot中了。
JAVA3D提供的API中,可用于生成Point的对象有: PointArray IndexedPointArray
1.PointArray
PointArray的构造函数为:
PointArray( int vertexCount, int vertexFormat );这里,vertexCount表示应生成的点的数目,vertexFormat表示所需要的顶点的格式。
点、线、面几何体所需要的顶点的格式有:
COORDINATES 顶点坐标数组
NORMALS 顶点法向数组
COLOR_3 不带alpha值的颜色数组
COLOR_4 带alpha值的颜色数组
TEXTURE_COORDINATE_2 二维纹理坐标数组
TEXTURE_COORDINATE_3 三维纹理坐标数组
2.IndexedPointArray
IndexedPointArray的构造函数为:
IndexedPointArray( int vertexCount, int vertexFormat,int indexCount );
利用本函数,我们可以从众多的点中,选择特定的点来显示。这里,vertexCount表示顶点坐标数组所提供的点的总个数,indexCount表示最终应生成的点的个数。JAVA3D可以生成任意大小的点,并且可以使点为方点或圆点。
3.3.2直线的生成
利用JAVA3D的一些对象,生成各种直线。可以生成直线的对象有:
1.LineArray
2.LineStripArray
3.IndexedLineArray
4.IndexedLineStripArray
我们可以根据各种不同的情况,生成不同的直线,如给定宽度的直线、虚线等。相应的的方法有:setLineWidth(float lineWidth)
setLinePattern(int linePattern)
setLineAntialiasingEnable(boolean state)
对于线型linePattern有以下数据可选:
int PATTERN_SOLID,int PATTERN_DASH,int PATTERN_DOT,int PATTERN_DASH_DOT
这些内容对所有种类的直线都有效。
3.3.3面的生成
生成平面的对象及其定义
JAVA3D可通过编程显示出面来,面有两种:三角形和四边形,相应的对象为Triangle和Quad。
JAVA3D用于生成平面的对象有:
1.TriangleArray
2.QuadArray
3.TriangleStripArray
4.TriangleFanArray
5.IndexedTriangleArray
6.IndexedTriangleStripArray
7.IndexedTriangleFanArray
§3.4 外部复杂形体的调用
利用前面介绍的方法生成我们所需要的基本形体,生成点、线、平面。但有的时候,我们需要用到其它格式的三维形体,如VRML2.0格式的图形文件,AUTOCAD绘出的DWG格式的三维形体,3DS MAX绘制出的复杂形体。本文转载自http://www.biyezuopin.vip/onews.asp?id=14545对于这些形体,我们可以非常方便地将其用到JAVA3D程序中去。下面我们介绍一些图形格式在JAVA3D中的应用方法。
一.Wavefront的OBJ格式的图形文件的调用
JAVA3D编译环境所带的UTILITY有两个LOADER,一个可用来调用Wavefront软件的OBJ格式的三维图形格式文件,一个可用来调用Lightwave软件的LWS及LWO格式的三维图形格式文件。
为了使JAVA3D能够调用Wavefront的OBJ格式的图形文件,程序的头四行import语句就是用来处理Wavefront的OBJ格式的图形文件,第五行的import语句则是打开外部文件之用。
import com.sun.j3d.loaders.objectfile.ObjectFile;
import com.sun.j3d.loaders.ParsingErrorException;
import com.sun.j3d.loaders.IncorrectFormatException;
import com.sun.j3d.loaders.Scene;
import java.io.*;
二.VRML2.0(VRML97)图形文件在JAVA3D中的应用简介
利用VRML97的LOADER我们可以在JAVA3D程序中方便地调用VRML图形。调用VRML97程序就象调用Wavefront的OBJ一样简单。
三.AUTOCAD R14的DWG图形及3DS MAX图形在JAVA3D中的应用。
在三维图形生成过程中,国内目前大量使用AUTOCAD及3DS MAX等软件。对于3DS MAX软件,处理起来非常方便 3DS MAX可以将其图形直接输出成VRML97格式。对于AUTOCAD R14来说,目前还不太方便,需借助第三方软件转换成JAVA3D支持格式。

/**  @(#)Corners.java 1.3 98/02/20 14:30:07** Copyright (c) 1996-1998 Sun Microsystems, Inc. All Rights Reserved.** Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,* modify and redistribute this software in source and binary code form,* provided that i) this copyright notice and license appear on all copies of* the software; and ii) Licensee does not utilize the software in a manner* which is disparaging to Sun.** This software is provided "AS IS," without a warranty of any kind. ALL* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE* POSSIBILITY OF SUCH DAMAGES.** This software is not designed or intended for use in on-line control of* aircraft, air traffic, aircraft navigation or aircraft communications; or in* the design, construction, operation or maintenance of any nuclear* facility. Licensee represents and warrants that it will not use or* redistribute the Software for such purposes.*/
package Java3DApplet;
import java.applet.Applet;
import java.awt.event.*;
import javax.media.j3d.*;
import javax.vecmath.*;public class Corners extends Object {private Group group;private Shape3D shape1;private Shape3D shape2;private Shape3D shape3;private Shape3D shape4;private Shape3D shape5;private Shape3D shape6;private Shape3D shape7;private Shape3D shape8;private static final float[] verts1 = {// Front Face-1.05f,  0.45f,  1.05f,  -0.45f,  0.45f,  1.05f,-0.45f,  1.05f,  1.05f,  -1.05f,  1.05f,  1.05f,// Back Face-1.05f,  0.45f,  0.45f,  -1.05f,  1.05f,  0.45f,-0.45f,  1.05f,  0.45f,  -0.45f,  0.45f,  0.45f,// Right Face-0.45f,  0.45f,  1.05f,  -0.45f,  0.45f,  0.45f,-0.45f,  1.05f,  0.45f,  -0.45f,  1.05f,  1.05f,// Left Face-1.05f,  0.45f,  0.45f,  -1.05f,  0.45f,  1.05f,-1.05f,  1.05f,  1.05f,  -1.05f,  1.05f,  0.45f,// Top Face-1.05f,  1.05f,  1.05f,  -0.45f,  1.05f,  1.05f,-0.45f,  1.05f,  0.45f,  -1.05f,  1.05f,  0.45f,// Bottom Face-1.05f,  0.45f,  0.45f,  -0.45f,  0.45f,  0.45f,-0.45f,  0.45f,  1.05f,  -1.05f,  0.45f,  1.05f,};private static final float[] verts2 = new float[72];private static final float[] verts3 = new float[72];private static final float[] verts4 = new float[72];private static final float[] verts5 = new float[72];private static final float[] verts6 = new float[72];private static final float[] verts7 = new float[72];private static final float[] verts8 = new float[72];private static final float[] normals = {// Front Face0.0f,  0.0f,  1.0f,     0.0f,  0.0f,  1.0f,0.0f,  0.0f,  1.0f,     0.0f,  0.0f,  1.0f,// Back Face0.0f,  0.0f, -1.0f,     0.0f,  0.0f, -1.0f,0.0f,  0.0f, -1.0f,     0.0f,  0.0f, -1.0f,// Right Face1.0f,  0.0f,  0.0f,     1.0f,  0.0f,  0.0f,1.0f,  0.0f,  0.0f,     1.0f,  0.0f,  0.0f,// Left Face-1.0f,  0.0f,  0.0f,    -1.0f,  0.0f,  0.0f,-1.0f,  0.0f,  0.0f,    -1.0f,  0.0f,  0.0f,// Top Face0.0f,  1.0f,  0.0f,     0.0f,  1.0f,  0.0f,0.0f,  1.0f,  0.0f,     0.0f,  1.0f,  0.0f,// Bottom Face0.0f, -1.0f,  0.0f,     0.0f, -1.0f,  0.0f,0.0f, -1.0f,  0.0f,     0.0f, -1.0f,  0.0f,};private static final float[] textCoords = {// Front Face1.0f,  0.0f,            1.0f,  1.0f,0.0f,  1.0f,            0.0f,  0.0f,// Back Face1.0f,  0.0f,            1.0f,  1.0f,0.0f,  1.0f,            0.0f,  0.0f,// Right Face1.0f,  0.0f,            1.0f,  1.0f,0.0f,  1.0f,            0.0f,  0.0f,// Left Face1.0f,  0.0f,            1.0f,  1.0f,0.0f,  1.0f,            0.0f,  0.0f,// Top Face1.0f,  0.0f,            1.0f,  1.0f,0.0f,  1.0f,            0.0f,  0.0f,// Bottom Face1.0f,  0.0f,            1.0f,  1.0f,0.0f,  1.0f,            0.0f,  0.0f};public Corners(Appearance appearance) {int i;for (i=0; i<72; i+=3) {verts2[i]   = verts1[i] + 1.5f;verts2[i+1] = verts1[i+1];verts2[i+2] = verts1[i+2];}for (i=0; i<72; i+=3) {verts3[i]   = verts2[i];verts3[i+1] = verts2[i+1] - 1.5f;verts3[i+2] = verts2[i+2];}for (i=0; i<72; i+=3) {verts4[i]   = verts1[i];verts4[i+1] = verts1[i+1] - 1.5f;verts4[i+2] = verts1[i+2];}for (i=0; i<72; i+=3) {verts5[i]   = verts1[i];verts5[i+1] = verts1[i+1];verts5[i+2] = verts1[i+2]- 1.5f;verts6[i]   = verts2[i];verts6[i+1] = verts2[i+1];verts6[i+2] = verts2[i+2] - 1.5f;verts7[i]   = verts3[i];verts7[i+1] = verts3[i+1];verts7[i+2] = verts3[i+2] - 1.5f;verts8[i]   = verts4[i];verts8[i+1] = verts4[i+1];verts8[i+2] = verts4[i+2] - 1.5f;}QuadArray quadArray1 = new QuadArray(24, QuadArray.COORDINATES |QuadArray.NORMALS         |QuadArray.TEXTURE_COORDINATE_2);quadArray1.setCoordinates(0, verts1);quadArray1.setNormals(0, normals);quadArray1.setTextureCoordinates(0, textCoords);QuadArray quadArray2 = new QuadArray(24, QuadArray.COORDINATES |QuadArray.NORMALS         |QuadArray.TEXTURE_COORDINATE_2);quadArray2.setCoordinates(0, verts2);quadArray2.setNormals(0, normals);quadArray2.setTextureCoordinates(0, textCoords);QuadArray quadArray3 = new QuadArray(24, QuadArray.COORDINATES |QuadArray.NORMALS         |QuadArray.TEXTURE_COORDINATE_2);quadArray3.setCoordinates(0, verts3);quadArray3.setNormals(0, normals);quadArray3.setTextureCoordinates(0, textCoords);QuadArray quadArray4 = new QuadArray(24, QuadArray.COORDINATES |QuadArray.NORMALS         |QuadArray.TEXTURE_COORDINATE_2);quadArray4.setCoordinates(0, verts4);quadArray4.setNormals(0, normals);quadArray4.setTextureCoordinates(0, textCoords);QuadArray quadArray5 = new QuadArray(24, QuadArray.COORDINATES |QuadArray.NORMALS         |QuadArray.TEXTURE_COORDINATE_2);quadArray5.setCoordinates(0, verts5);quadArray5.setNormals(0, normals);quadArray5.setTextureCoordinates(0, textCoords);QuadArray quadArray6 = new QuadArray(24, QuadArray.COORDINATES |QuadArray.NORMALS         |QuadArray.TEXTURE_COORDINATE_2);quadArray6.setCoordinates(0, verts6);quadArray6.setNormals(0, normals);quadArray6.setTextureCoordinates(0, textCoords);QuadArray quadArray7 = new QuadArray(24, QuadArray.COORDINATES |QuadArray.NORMALS         |QuadArray.TEXTURE_COORDINATE_2);quadArray7.setCoordinates(0, verts7);quadArray7.setNormals(0, normals);quadArray7.setTextureCoordinates(0, textCoords);QuadArray quadArray8 = new QuadArray(24, QuadArray.COORDINATES |QuadArray.NORMALS         |QuadArray.TEXTURE_COORDINATE_2);quadArray8.setCoordinates(0, verts8);quadArray8.setNormals(0, normals);quadArray8.setTextureCoordinates(0, textCoords);shape1 = new Shape3D(quadArray1, appearance);shape2 = new Shape3D(quadArray2, appearance);shape3 = new Shape3D(quadArray3, appearance);shape4 = new Shape3D(quadArray4, appearance);shape5 = new Shape3D(quadArray5, appearance);shape6 = new Shape3D(quadArray6, appearance);shape7 = new Shape3D(quadArray7, appearance);shape8 = new Shape3D(quadArray8, appearance);group = new Group();group.addChild(shape1);group.addChild(shape2);group.addChild(shape3);group.addChild(shape4);group.addChild(shape5);group.addChild(shape6);group.addChild(shape7);group.addChild(shape8);}public Group getChild() {return group;}
}

















基于Java3D的网络三维可视化原型系统设计与实现相关推荐

  1. cesium 车流_基于Cesium的城市三维可视化地下管线系统的建立方法与流程

    本发明属于虚拟三维管线领域,特别是涉及基于Cesium的城市三维可视化地下管线系统的建立方法. 背景技术: 随着我国经济的快速发展,城市规模也在不断地扩大,而城市地下管网的铺设力度也不断加大,城市地下 ...

  2. 基于JAVA3D的网络三维技术的设计与实现

    摘 要 互联网的出现及飞速发展使IT业的各个领域发生了深刻的变化,它必然引发一些新技术的出现.3D图形技术并不是一个新话题,在图形工作站以至于PC机上早已日臻成熟,并已应用到各个领域.然而互联网的出现 ...

  3. 基于PHP的网络数据包分析系统设计与实现

    目 录 1 引言 1 1.1 课题背景 1 1.2 国内外研究现状 1 1.3 本课题研究的意义 1 1.4 本课题的理论基础 1 2 网络数据包分析系统概述 2 2.1 网络数据包分析的意义 2 2 ...

  4. 基于BIM+GIS技术,如何构建智慧楼宇三维可视化管控平台?

    传统园区一直面临着各类难题,例如管理效率低.规章制度没法结合.智能安防工作能力不强.机器设备监管分散化等一系列问题.现阶段,基于BIM+GIS技术构建的智慧楼宇三维可视化管控平台,可以实现建筑全生命周 ...

  5. 基于Spring Cloud + MyBatis的分布式架构网约车平台(DD 打车)后端原型系统设计与实现

    资源下载地址:https://download.csdn.net/download/sheziqiong/85638879 资源下载地址:https://download.csdn.net/downl ...

  6. 基于Java+hadoop网络云盘上传下载系统设计与实现

    目 录 网络云盘上传下载系统摘要----------------------------------5 The Network Cloud Disk`s Upload and DownloadAbst ...

  7. python三维矩阵可视化_科学计算三维可视化---Mlab基础(基于Numpy数组的绘图函数)...

    Mlab了解 Mlab是Mayavi提供的面向脚本的api,他可以实现快速的三维可视化,Mayavi可以通过Mlab的绘图函数对Numpy数组建立可视化. 过程为: .建立数据源 .使用Filter( ...

  8. 基于深度学习的近红外掌纹识别原型系统设计与实现

    基于深度学习的近红外掌纹识别原型系统设计与实现 一.绪论 二.深度学习知识 三.Tensorflow 四.卷积神经网络 五.掌纹识别理论 掌纹图像采集 掌纹图像预处理 掌纹特征提取 掌纹特征匹配 掌纹 ...

  9. 基于gis三维可视化技术的智慧城市建设

    在平安城市规划建设中,应急指挥与智能监控系统根据选用监控设备在二维在线地图上显示信息的方法,可以保持集视频监控系统.GIS.GPS定位.周边预防(如采电子脉冲.振动光缆电缆等).目标识别.智能视频.视 ...

最新文章

  1. StackToQueue
  2. WPF获取鼠标相对于屏幕的绝对位置
  3. Thrift IDL基本语法
  4. STL 之swap, iter_swap, swap_ranges
  5. python 横坐标旋转,python 横坐标旋转
  6. python网络爬虫系列(二)——ProxyHandler处理器实现代理IP
  7. Codeforces Gym 101142C:CodeCoder vs TopForces(搜索)
  8. LeNet-5实战minist——搭建卷积网络模型
  9. lisp语言与python_5种语言混合编程:C++、JS、python、Lisp、汇编
  10. 无法启动因为计算机丢失ac1st16,重装系统后cad2006打不开.提示因为计算机中丢失ac1st16.dll...
  11. 放弃微博,继续回来写月经
  12. cryptojs php 互通_如何实现PHP7和CryptoJS的AES加密方式互通?
  13. 谨慎试之:libopencv_core.so.3.4, needed by //usr/local/lib/libopencv_imgcodecs.so
  14. Graph DataBase介绍
  15. 阿里面试——机器学习岗四个面试案例
  16. Unity Shader------Specular(高光反射)计算
  17. 自定义一个Chrome翻译插件
  18. linux装pl2303驱动下载,Linux下安装USB转串口驱动(PL2303)
  19. 踩坑之路:finish方法执行后居然还有这种操作?
  20. 5g通用模组是什么_芯讯通:定义5G通用模组,助力5G商用落地

热门文章

  1. 2022张宇考研基础30讲 线性代数 第一讲 行列式
  2. 使用高通QXDM工具实现Android设备网络制式更改(如仅注册LTE网络)(独家!)
  3. 苹果电脑截屏的几种办法
  4. PHP比java好学?_php好学还是java好学,学php有前途吗
  5. ECharts动画使用
  6. html页面滑动不流畅,解决页面使用overflow:scroll在移动端iOS系统上滑动出现卡顿的问题...
  7. Android 开发之 QQ变声功能实现
  8. vue点击事件转圈等待返回取消
  9. ensp40号41号错误报告情况以及解决办法细碎点总结
  10. Python-Django毕业设计志远奶茶网络设计(程序+LW).