您当前的位置:首页 > IT编程 > C++
| C语言 | Java | VB | VC | python | Android | TensorFlow | C++ | oracle | 学术与代码 | cnn卷积神经网络 | gnn | 图像修复 | Keras | 数据集 | Neo4j | 自然语言处理 | 深度学习 | 医学CAD | 医学影像 | 超参数 | pointnet | pytorch | 异常检测 | Transformers | 情感分类 | 知识图谱 |

自学教程:C++ BBox函数代码示例

51自学网 2021-06-01 19:49:10
  C++
这篇教程C++ BBox函数代码示例写得很实用,希望能帮到您。

本文整理汇总了C++中BBox函数的典型用法代码示例。如果您正苦于以下问题:C++ BBox函数的具体用法?C++ BBox怎么用?C++ BBox使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。

在下文中一共展示了BBox函数的28个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。

示例1: BBox

BBox Track::getBBox() const{    if (!points.length()) {        return BBox();    }    float left, top, bottom, right;    left = right = points[0]._lon;    top = bottom = points[0]._lat;    QList<TrackPoint>::const_iterator i = points.begin();    ++i;    for (; i != points.end(); ++i) {        float lat = (*i)._lat;        float lon = (*i)._lon;        if ( lon < left) {            left = lon;        } else if (lon > right) {            right = lon;        }        if ( lat > top) {            top = lat;        } else if (lat < bottom) {            bottom = lat;        }    }    return BBox(left, top, right, bottom);}
开发者ID:overplumbum,项目名称:QuickTrack,代码行数:30,


示例2: Collide

bool SHAPE_RECT::Collide( const SEG& aSeg, int aClearance ) const{    //VECTOR2I pmin = VECTOR2I( std::min( aSeg.a.x, aSeg.b.x ), std::min( aSeg.a.y, aSeg.b.y ) );    //VECTOR2I pmax = VECTOR2I( std::max( aSeg.a.x, aSeg.b.x ), std::max( aSeg.a.y, aSeg.b.y ));    //BOX2I r( pmin, VECTOR2I( pmax.x - pmin.x, pmax.y - pmin.y ) );    //if( BBox( 0 ).SquaredDistance( r ) > aClearance * aClearance )    //    return false;    if( BBox( 0 ).Contains( aSeg.A ) || BBox( 0 ).Contains( aSeg.B ) )        return true;    VECTOR2I vts[] = { VECTOR2I( m_p0.x, m_p0.y ),                        VECTOR2I( m_p0.x, m_p0.y + m_h ),                        VECTOR2I( m_p0.x + m_w, m_p0.y + m_h ),                        VECTOR2I( m_p0.x + m_w, m_p0.y ),                        VECTOR2I( m_p0.x, m_p0.y ) };    for( int i = 0; i < 4; i++ )    {        SEG s( vts[i], vts[i + 1], i );        if( s.Distance( aSeg ) < aClearance )            return true;    }    return false;}
开发者ID:zhihuitech,项目名称:kicad-source-mirror,代码行数:28,


示例3: compressBBox

uint32_t EBVHAccel::flattenEBVHTree(EBVHBuildNode *node, uint32_t *offset, BBox boxToBoundOn) {    LinearEBVHNode *linearNode = &nodes[*offset];        BBox compressedBox = compressBBox(node->bounds, boxToBoundOn);    linearNode->bounds_x0 = compressedBox.pMin.x;    linearNode->bounds_y0 = compressedBox.pMin.y;    linearNode->bounds_z0 = compressedBox.pMin.z;    linearNode->bounds_x1 = compressedBox.pMax.x;    linearNode->bounds_y1 = compressedBox.pMax.y;    linearNode->bounds_z1 = compressedBox.pMax.z;    BBox uncompressedBox = uncompressBBox(BBox(Point(linearNode->bounds_x0, linearNode->bounds_y0, linearNode->bounds_z0), Point(linearNode->bounds_x1, linearNode->bounds_y1, linearNode->bounds_z1)), boxToBoundOn);    uint32_t myOffset = (*offset)++;    if (node->nPrimitives > 0) {        Assert(!node->children[0] && !node->children[1]);        linearNode->primitivesOffset = node->firstPrimOffset;        linearNode->nPrimitives = node->nPrimitives;    }    else {        // Creater interior flattened EBVH node        linearNode->axis = node->splitAxis;        linearNode->nPrimitives = 0;        flattenEBVHTree(node->children[0], offset, BBox(Point(uncompressedBox.pMin.x,uncompressedBox.pMin.y,uncompressedBox.pMin.z), Point(uncompressedBox.pMax.x,uncompressedBox.pMax.y,uncompressedBox.pMax.z)));        linearNode->secondChildOffset = flattenEBVHTree(node->children[1],                                                       offset, BBox(Point(uncompressedBox.pMin.x,uncompressedBox.pMin.y,uncompressedBox.pMin.z), Point(uncompressedBox.pMax.x,uncompressedBox.pMax.y,uncompressedBox.pMax.z)));    }    return myOffset;}
开发者ID:benigeri,项目名称:pbrt_bioluminescence,代码行数:30,


示例4: BBox

bool SHAPE_LINE_CHAIN::PointInside( const VECTOR2I& aPt, int aAccuracy ) const{    BOX2I bbox = BBox();    bbox.Inflate( aAccuracy );    if( !m_closed || PointCount() < 3 || !BBox().Contains( aPt ) )        return false;    bool inside = false;    /**     * To check for interior points, we draw a line in the positive x direction from     * the point.  If it intersects an even number of segments, the point is outside the     * line chain (it had to first enter and then exit).  Otherwise, it is inside the chain.     *     * Note: slope might be denormal here in the case of a horizontal line but we require our     * y to move from above to below the point (or vice versa)     */    for( int i = 0; i < PointCount(); i++ )    {        const auto p1 = CPoint( i );        const auto p2 = CPoint( i + 1 ); // CPoint wraps, so ignore counts        const auto diff = p2 - p1;        if( diff.y != 0 )        {            const int d = rescale( diff.x, ( aPt.y - p1.y ), diff.y );            if( ( ( p1.y > aPt.y ) != ( p2.y > aPt.y ) ) && ( aPt.x - p1.x < d ) )                inside = !inside;        }    }    return inside && !PointOnEdge( aPt, aAccuracy );}
开发者ID:KiCad,项目名称:kicad-source-mirror,代码行数:34,


示例5: BBox

BBox PhysicObject::getPhysBBox() {	if (!isPhysicsInitialized())		return BBox();	btVector3 min;	btVector3 max;	rigidBody->getAabb(min, max);	return BBox(CVector(min.x() * 100.0f, max.y() * 100.0f, min.z() * 100.0f),			CVector(max.x() * 100.0f, min.y() * 100.0f, max.z() * 100.0f));}
开发者ID:muhaos,项目名称:MHEngine,代码行数:11,


示例6: InsertFace

void R3MeshSearchTree::InsertFace(R3MeshFace *face){  // Check if face intersects box  if (!R3Intersects(mesh, face, BBox())) return;  // Create container  R3MeshSearchTreeFace *face_container = new R3MeshSearchTreeFace(mesh, face);  assert(face_container);  // Insert face into root  InsertFace(face_container, root, BBox(), 0);}
开发者ID:kyzyx,项目名称:empty-room,代码行数:13,


示例7: read_gamemap

void GameScreenSet::deserialize(GameState *gs, SerializeBuffer &serializer) {    serializer.read_int(current_screen);    simulation_map = read_gamemap(gs, serializer);    serializer.read_container(screens, [&](GameScreen& screen) {        screen.deserialize(gs, serializer);    });    GameSettings& settings = gs->game_settings();    int n_local_players = 0;    for (PlayerDataEntry &player: gs->player_data().all_players()) {        if (player.is_local_player) {            n_local_players++;        }    }    // Number of split-screens tiled together    int n_x = 1, n_y = 1;    if (n_local_players <= 2) {        n_x = n_local_players;    } else if (n_local_players <= 4) {        // More than 2, less than 4? Try 2x2 tiling        n_x = 2, n_y = 2;    } else if (n_local_players <= 6) {        n_x = 3, n_y = 2;    } else {        LANARTS_ASSERT(n_local_players <= 9);        // Last resort, Try 3x3 tiling        n_x = 3, n_y = 3;    }    const int WIDTH = settings.view_width / n_x;    const int HEIGHT = settings.view_height / n_y; // / N_PLAYERS;    std::vector<BBox> bounding_boxes;    for (GameScreen& screen : screens) {        const int x1 = (screen.index % n_x) * WIDTH, y1 = (screen.index / n_x) * HEIGHT;        bounding_boxes.push_back(BBox {x1, y1, x1 + WIDTH, y1 + HEIGHT});    }    if (bounding_boxes.size() == 3) {        bounding_boxes[1] = {WIDTH, 0, settings.view_width, settings.view_height};    }    for (GameScreen& screen : screens) {        BBox b = bounding_boxes[screen.index];        screen.window_region = b;        screen.hud = GameHud {                BBox(b.x2 - GAME_SIDEBAR_WIDTH, b.y1, b.x2, b.y2),                BBox(b.x1, b.y1, b.x2 - GAME_SIDEBAR_WIDTH, b.y2)        };        screen.view = GameView {0, 0, b.width() - GAME_SIDEBAR_WIDTH, b.height()};    }}
开发者ID:ludamad,项目名称:lanarts,代码行数:49,


示例8: Shape

NaiadFoamBox::NaiadFoamBox(const Transform *o2w, const Transform *w2o,                           bool ro, Reference<NaiadFoam> par, const Nb::ParticleShape & particle, int blockID)    : Shape(o2w, w2o, ro), parent(par) {    //Get the blocks of particles    const Nb::BlockArray3f& blocksPos = particle.constBlocks3f("position");    const Nb::Block3f& blockPos = blocksPos(blockID);    density = blockPos.size();    bb = BBox(Point(blockPos.min().v[0],                    blockPos.min().v[1],                    blockPos.min().v[2]),              Point(blockPos.max().v[0],                    blockPos.max().v[1],                    blockPos.max().v[2]));    //for (int pIdx = 0; pIdx < 1; ++pIdx) {    for (int pIdx = 0; pIdx < blockPos.size(); pIdx += 20) {        Point pos(blockPos.data()[pIdx].v[0],                  blockPos.data()[pIdx].v[1],                  blockPos.data()[pIdx].v[2]);        float r = 0.03f;        particles.push_back(NaiadFoamParticle(pos,r, this));#ifdef VDB        vdb_sample(0.01);        vdb_color(1.0f, 1.0f, 1.0f);        vdb_point(pos.x, pos.y, pos.z);#endif    }}
开发者ID:karlssonper,项目名称:cs348b,代码行数:33,


示例9: Intersects

RNBoolean R3Model::Intersects(const R3Ray& ray,   R3Point *hit_point, R3Vector *hit_normal,   RNScalar *hit_t, int *hit_triangle_index) const{  // Check triangles  if (!triangles) return FALSE;  // Check bounding box  if (!R3Intersects(ray, BBox())) return FALSE;  // Check each triangle for intersection  RNScalar min_t = FLT_MAX;  for (int i = 0; i < NTriangles(); i++) {    const R3Triangle *triangle = Triangle(i);    R3Point point;    R3Vector normal;    RNScalar t;    if (R3Intersects(ray, *triangle, &point, &normal, &t) == R3_POINT_CLASS_ID) {      if (t < min_t) {        if (hit_point) *hit_point = point;        if (hit_normal) *hit_normal = normal;        if (hit_triangle_index) *hit_triangle_index = i;        if (hit_t) *hit_t = t;        min_t = t;      }    }  }  // Return whether hit any triangle  return (min_t == FLT_MAX) ? FALSE : TRUE;}
开发者ID:cricklet,项目名称:Path-Tracer,代码行数:32,


示例10: BBox

	BBox Triangle::Bound() const {		const VectorArray& vertices = mesh->vertices;		Vector3dF p0 = vertices[indexes[0]];		Vector3dF p1 = vertices[indexes[1]];		Vector3dF p2 = vertices[indexes[2]];		return BBox(p0, p1).Union(p2);	}
开发者ID:voyagingmk,项目名称:renderer,代码行数:7,


示例11: BBox

BBox Triangle::get_bbox() const {    // TODO:   // compute the bounding box of the triangle    return BBox();}
开发者ID:462cmu,项目名称:asst3_pathtracer,代码行数:7,


示例12: return

BBox Rectangle::get_bounding_box(void) {	double delta = 0.0001; 	return(BBox(std::min(p0.x, p0.x + a.x + b.x) - delta, std::max(p0.x, p0.x + a.x + b.x) + delta,                    std::min(p0.y, p0.y + a.y + b.y) - delta, std::max(p0.y, p0.y + a.y + b.y) + delta,                     std::min(p0.z, p0.z + a.z + b.z) - delta, std::max(p0.z, p0.z + a.z + b.z) + delta));}
开发者ID:dunkirk16,项目名称:rayTracer,代码行数:7,


示例13: assert

BBox SpherePrimitive::wsBounds(Geo::Geometry::CPtr geometry) const{  assert(geometry != NULL);  assert(geometry->particles() != NULL);  if (!geometry->particles()) {    Log::warning("SpherePrimitive has no particles. "                 "Skipping bounds generation.");    return BBox();  }  BBox wsBBox;  AttrVisitor visitor(geometry->particles()->pointAttrs(), m_params);  Attr<V3f>   wsCenter("P");  Attr<float> radius("radius");  for (AttrVisitor::const_iterator i = visitor.begin(), end = visitor.end();        i != end; ++i) {    i.update(wsCenter);    i.update(radius);    wsBBox.extendBy(wsCenter.as<Vector>() + radius.as<Vector>());    wsBBox.extendBy(wsCenter.as<Vector>() - radius.as<Vector>());  }  return wsBBox;}
开发者ID:DocSavage,项目名称:pvr,代码行数:27,


示例14: Outline

void R3MeshSearchTree::Outline(void) const{  // Draw kdtree nodes recursively  if (!root) return;  Outline(root, BBox());}
开发者ID:kyzyx,项目名称:empty-room,代码行数:7,


示例15: FindIntersection

void R3MeshSearchTree::FindIntersection(const R3Ray& ray, R3MeshIntersection& closest,  RNScalar min_t, RNScalar max_t,  int (*IsCompatible)(const R3Point&, const R3Vector&, R3Mesh *, R3MeshFace *, void *), void *compatible_data){  // Initialize result  closest.type = R3_MESH_NULL_TYPE;  closest.vertex = NULL;  closest.edge = NULL;  closest.face = NULL;  closest.point = R3zero_point;  closest.t = 0;  // Check root  if (!root) return;  // Update mark (used to avoid checking same face twice)  mark++;  // Search nodes recursively  FindIntersection(ray, closest,    min_t, max_t,    IsCompatible, compatible_data,    root, BBox());}
开发者ID:kyzyx,项目名称:empty-room,代码行数:25,


示例16: Union

BBox Triangle::WorldBound() const {    // Get triangle vertices in _p1_, _p2_, and _p3_    const Point &p1 = mesh->p[v[0]];    const Point &p2 = mesh->p[v[1]];    const Point &p3 = mesh->p[v[2]];    return Union(BBox(p1, p2), p3);}
开发者ID:jmriviere,项目名称:pbrt-v2,代码行数:7,


示例17: BBox

BBox TrackList::getBBox() const{    if (!tracks.length()) {        return BBox();    }    BBox cur, max;    Track t = tracks.first();    max = t.getBBox();    QList<Track>::const_iterator i = tracks.begin();    ++i;    for (; i != tracks.end(); ++i) {        cur = (*i).getBBox();        if (cur.left < max.left) {            max.left = cur.left;        }        if (cur.top < max.top) {            max.top = cur.top;        }        if (cur.right > max.right) {            max.right = cur.right;        }        if (cur.bottom > max.bottom) {            max.bottom = cur.bottom;        }    }    return max;}
开发者ID:overplumbum,项目名称:QuickTrack,代码行数:30,


示例18: BBox

BVH::BVH(ObjMesh& _mesh){    mesh = _mesh;    //build work list    workList.reserve(mesh.faces.size());    for(auto i = 0; i < mesh.faces.size(); ++i)        workList.push_back(BVHPrimitiveInfo(i, BBox(mesh.vertices[mesh.faces[i].x], mesh.vertices[mesh.faces[i].y], mesh.vertices[mesh.faces[i].z])));    //recursive build    std::cout<<"Building BVH..."<<std::endl;    orderedPrims.reserve(mesh.faces.size());    root = RecursiveBuild(0, workList.size());    std::cout<<"Totoal nodes: "<<totalNodes<<std::endl;    std::cout<<"Max depth: "<<maxDepth<<std::endl;    //replace mesh faces order with ordered one    mesh.faces.swap(orderedPrims);    //build linear bvh    lbvh.reserve(totalNodes);    for(auto i = 0; i < totalNodes; ++i)        lbvh.push_back(LBVHNode());    uint32_t offset = 0;    Flatten(root, &offset);    std::cout<<"Root max: ("<<lbvh[0].bMax.x<<", "<<lbvh[0].bMax.y<<", "<<lbvh[0].bMax.z<<")"<<std::endl;    std::cout<<"Root min: ("<<lbvh[0].bMin.x<<", "<<lbvh[0].bMin.y<<", "<<lbvh[0].bMin.z<<")"<<std::endl;}
开发者ID:sunwj,项目名称:SunPathTracer-CUDA-Path-tracer,代码行数:28,


示例19: PickBlock

void Player::DoBlockPicking() {	static int counter = 0;	static bool mouseStateLastTick = false;	PickBlock();	if (!Window::HasFocus()) {		return;	}	if (picked && !mouseStateLastTick) {		if (Input::MouseRight()) {			int old = Game::world->GetBlock(pickedBlock + side);			Game::world->SetBlock(pickedBlock + side, Block::Test);			if (BoundingBoxD::Block(pickedBlock + side).Intersects(BBox())) {				Game::world->SetBlock(pickedBlock + side, old);			} else {				Game::worldRenderer->UpdateBlock(pickedBlock + side);			}		} else if (Input::MouseLeft()) {			Game::world->SetBlock(pickedBlock, Block::Air);			Game::worldRenderer->UpdateBlock(pickedBlock);		}		PickBlock();		counter = 0;	}	mouseStateLastTick = Input::MouseLeft() || Input::MouseRight();	if (counter > 250) {		mouseStateLastTick = false;	}	counter += Game::TickMS;}
开发者ID:xunatai,项目名称:cubiverse,代码行数:35,


示例20: BBox

BBox Triangle::get_bounding_box(void) const {  double delta = 0.000001;  return BBox(min(min(v0.x, v1.x), v2.x) - delta, max(max(v0.x, v1.x), v2.x) + delta,         min(min(v0.y, v1.y), v2.y) - delta, max(max(v0.y, v1.y), v2.y) + delta,         min(min(v0.z, v1.z), v2.z) - delta, max(max(v0.z, v1.z), v2.z) + delta);}
开发者ID:vmichele,项目名称:raytracer,代码行数:7,


示例21: return

BBox SmoothTriangle::get_bounding_box(void) {	double delta = 0.0001; 		return(BBox(std::min(std::min(v0.x, v1.x), v2.x) - delta, std::max(std::max(v0.x, v1.x), v2.x) + delta,                     std::min(std::min(v0.y, v1.y), v2.y) - delta, std::max(std::max(v0.y, v1.y), v2.y) + delta,                     std::min(std::min(v0.z, v1.z), v2.z) - delta, std::max(std::max(v0.z, v1.z), v2.z) + delta));}
开发者ID:dunkirk16,项目名称:rayTracer,代码行数:7,


示例22: DoOrient

void Player::DoOrient() {	//if (noclip) return;	Vector3I newUp = Game::world->GetUp(pos);	if (playerUp != newUp) {		glm::dmat4 oldOrientation = orientation;		Vector3I rotationAxis = playerUp.Cross(newUp);		glm::dmat4 rot = glm::gtc::matrix_transform::rotate(glm::dmat4(), 90.0, glm::dvec3(rotationAxis.ToGlmVec3()));		orientation = rot * orientation;		if (Game::world->Intersects(BBox())) {			orientation = oldOrientation;		} else {			playerUp = newUp;		}	}	Vector3D newSmoothUp = Game::world->GetUpSmooth(pos);	double angle = smoothUp.DegreesTo(newSmoothUp);	if (abs(angle) > 0.001) {		//glm::dmat4 oldOrientation = smoothOrientation;		Vector3D rotationAxis = smoothUp.Cross(newSmoothUp);		glm::dmat4 rot = glm::gtc::matrix_transform::rotate(glm::dmat4(), angle, glm::dvec3(rotationAxis.ToGlmVec3()));		smoothOrientation = rot * smoothOrientation;		smoothUp = newSmoothUp;	}}
开发者ID:xunatai,项目名称:cubiverse,代码行数:30,


示例23: Point

extern "C" DLLEXPORT VolumeRegion *CreateVolumeRegion(const Transform &volume2world,		const ParamSet &params) {	// Initialize common volume region parameters	Spectrum sigma_a = params.FindOneSpectrum("sigma_a", 0.);	Spectrum sigma_s = params.FindOneSpectrum("sigma_s", 0.);	float g = params.FindOneFloat("g", 0.);	Spectrum Le = params.FindOneSpectrum("Le", 0.);	Point p0 = params.FindOnePoint("p0", Point(0,0,0));	Point p1 = params.FindOnePoint("p1", Point(1,1,1));	int nitems;	const float *data = params.FindFloat("density", &nitems);	if (!data) {		Error("No /"density/" values provided for volume grid?");		return NULL;	}	int nx = params.FindOneInt("nx", 1);	int ny = params.FindOneInt("ny", 1);	int nz = params.FindOneInt("nz", 1);	if (nitems != nx*ny*nz) {		Error("VolumeGrid has %d density values but nx*ny*nz = %d",			nitems, nx*ny*nz);		return NULL;	}	return new VolumeGrid(sigma_a, sigma_s, g, Le, BBox(p0, p1),		volume2world, nx, ny, nz, data);}
开发者ID:BackupTheBerlios,项目名称:rendertoolbox-svn,代码行数:26,


示例24: Union

BBox Triangle::ObjectBound() const {	const Point &p1 = mMesh->p[mIndex[0]];	const Point &p2 = mMesh->p[mIndex[1]];	const Point &p3 = mMesh->p[mIndex[2]];	return Union(BBox((*worldToLocal)(p1), (*worldToLocal)(p2)),			(*worldToLocal)(p3));}
开发者ID:zq317157782,项目名称:RayTracer,代码行数:7,


示例25: BBox

BBox Heightfield::ObjectBound() const {    float minz = z[0], maxz = z[0];    for (int i = 1; i < nx*ny; ++i) {        if (z[i] < minz) minz = z[i];        if (z[i] > maxz) maxz = z[i];    }    return BBox(PbrtPoint(0,0,minz), PbrtPoint(1,1,maxz));}
开发者ID:AI42,项目名称:OM3D,代码行数:8,


示例26: BBox

BBox GameView::tile_region_covered() const {	int min_x = std::max(0, x / TILE_SIZE);	int min_y = std::max(0, y / TILE_SIZE);	int max_x = (std::min(world_width, x + width)) / TILE_SIZE;	int max_y = (std::min(world_height, y + height)) / TILE_SIZE;	return BBox(min_x, min_y, max_x, max_y);}
开发者ID:yi-juchung,项目名称:lanarts,代码行数:8,


示例27: m_error

 Glyph::Glyph(FT_GlyphSlotRec_ * glyph) : m_error(0) {   if(glyph) {     m_bbox = BBox(glyph);     m_advance = Nimble::Vector2(glyph->advance.x / 64.f, glyph->advance.y / 64.f);   } }
开发者ID:enuuros,项目名称:multitude,代码行数:8,


示例28: vec

BBox InfinitePlane::getBounds() const{    //get a vector from the plane, perpendicular to the normal    //if normal is (a,b,c) then a perpendicular vector is (c,c,-a-b)    Vector vec(normal.z,normal.z,-normal.x-normal.y);    //infinite bbox    return BBox(Point(vec.x,vec.y,vec.z)*(FLT_MIN),Point(vec.x,vec.y,vec.z)*(FLT_MAX));}
开发者ID:kmario23,项目名称:ray_tracer,代码行数:9,



注:本文中的BBox函数示例整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。


C++ BCD2BIN函数代码示例
C++ BB_T函数代码示例
万事OK自学网:51自学网_软件自学网_CAD自学网自学excel、自学PS、自学CAD、自学C语言、自学css3实例,是一个通过网络自主学习工作技能的自学平台,网友喜欢的软件自学网站。